Modificación de variables globales en el framework unitthest de Python

Estoy trabajando en una serie de pruebas unitarias en Python, algunas de las cuales dependen del valor de una variable de configuración. Estas variables se almacenan en un archivo de configuración de Python global y se utilizan en otros módulos. Me gustaría escribir pruebas unitarias para diferentes valores de las variables de configuración, pero aún no he encontrado una manera de hacer esto.

No tengo la posibilidad de volver a escribir las firmas de los métodos que estoy probando.

Esto es lo que me gustaría lograr:

from my_module import my_function_with_global_var class TestSomething(self.unittest): def test_first_case(self): from config import MY_CONFIG_VARIABLE MY_CONFIG_VARIABLE = True self.assertEqual(my_function_with_global_var(), "First result") def test_second_case(self): from config import MY_CONFIG_VARIABLE MY_CONFIG_VARIABLE = False self.assertEqual(my_function_with_global_var(), "Second result") 

Gracias.

Editar: Hizo el código de ejemplo más explícito.

Use unittest.mock.patch como en la respuesta de @Flimm , si está disponible para usted.


Respuesta original

No hagas esto

 from my_module import my_function_with_global_var 

Pero esto:

 import my_module 

Y luego puede inyectar MY_CONFIG_VARIABLE en el my_module importado, sin cambiar el sistema bajo prueba de la siguiente manera:

 class TestSomething(unittest.TestCase): # Fixed that for you! def test_first_case(self): my_module.MY_CONFIG_VARIABLE = True self.assertEqual(my_module.my_function_with_global_var(), "First result") def test_second_case(self): my_module.MY_CONFIG_VARIABLE = False self.assertEqual(my_module.my_function_with_global_var(), "Second result") 

Hice algo similar en mi respuesta a ¿Cómo puedo simular una entrada a stdin para pyunit? .

Probablemente quieras burlarte de esas variables globales. La ventaja de esto es que los globales se reinician una vez que terminas. Python se envía con un módulo de burla que te permite hacer esto.

unittest.mock.patch se utiliza como decorador:

 class TestSomething(self.unittest): @patch('config.MY_CONFIG_VARIABLE', True) def test_first_case(self): self.assertEqual(my_function_with_global_var(), "First result") 

También puedes usarlo como administrador de contexto:

  def test_first_case(self): with patch('config.MY_CONFIG_VARIABLE', True): self.assertEqual(my_function_with_global_var(), "First result") 

El código importa MY_CONFIG_VARIABLE en el ámbito local y luego sobrescribe inmediatamente el nombre con un objeto diferente. Eso no cambiará el valor en el módulo de config . Tratar

 import config config.MY_CONFIG_VARIABLE = False 

en lugar.