Testing en Python: Hacer mock de una variable global
Estaba intentando probar algunas variables globales con Python, especialmente para un script el cual contiene variables globales. Y después de intentarlo y fallar, pienso que puedo mostrarte la versión más simple de hacerlo.
🏃 La solución rápida
2
ENVS = { 'valor_real': True, 'otro_valor_real': False }5
mocker.patch("archivo_demo.ENVS", new={'MOCKED_NONE': None, 'MOCKED_VACIO': ''})
Después en tu archivo_demo la variable ENVS estará como mocked.
✏️ La solución detallada
Requerimientos
- Para facilidad del trabajo. Recomiendo la siguiente librería: https://pypi.org/project/pytest-mock/
¿Qué estaba intentando hacer?
Primero, supongamos que tengo un archivo llamado archivo_demo.py con el siguiente contenido (y donde la variable global está localizada).
4
ENVS = { 'valor_real': os.environ('VALOR_REAL'), 'otro_valor_real': os.environ('OTRO_VALOR_REAL') }
Si tratas de ejecutar metodo_simple va a mostrar el diccionario con valor_real y otro_valor_real allí.
Ahora tenemos el siguiente archivo de test.
2
from archivo_demo import metodo_simple4
def testear_si_metodo_simple_funciona():5
assert metodo_simple() == 0
Ya sé que el test se ve simple, pero se asegura al menos de retornar un valor cero después de mostrar los valores ENVs.
👾 Sobreescribiendo y simulando (hacer un mock de) las variables
Pero como puedes ver, estamos llamando las variables de entorno de la computadora que usemos, y si tú escribes tus tests, esperando tenerlas en el servidor CI/CD, entonces los tests comenzarán a fallar. ¿Cómo podemos evitar eso y decirle a nuestro servidor de testing (o pipeline de testing) que queremos valores fijos?
Si instalaste la librería mencionada arriba, en la sección de requerimientos, es muy fácil comenzar a mockear valores. Así que solamente necesitamos agregar una sola línea.
2
from archivo_demo import metodo_simple4
@mocker.patch("archivo_demo.ENVS", new={'VALOR_REAL_MOCKED': None, 'OTRO_VALOR_REAL_MOCKED': ''})5
def testear_si_metodo_simple_funciona():6
assert metodo_simple() == 0
Y tus tests no ejecutarán la variable ENVS y, por lo tanto, tampoco llamarán a os.environ.