Quiero entender cómo @patch
funciona una función desde un módulo importado.
Aquí es donde estoy hasta ahora.
app / mocking.py:
from app.my_module import get_user_name
def test_method():
return get_user_name()
if __name__ == "__main__":
print "Starting Program..."
test_method()
app / my_module / __ init__.py:
def get_user_name():
return "Unmocked User"
test / mock-test.py:
import unittest
from app.mocking import test_method
def mock_get_user():
return "Mocked This Silly"
@patch('app.my_module.get_user_name')
class MockingTestTestCase(unittest.TestCase):
def test_mock_stubs(self, mock_method):
mock_method.return_value = 'Mocked This Silly')
ret = test_method()
self.assertEqual(ret, 'Mocked This Silly')
if __name__ == '__main__':
unittest.main()
Esto no funciona como esperaba. El módulo "parcheado" simplemente devuelve el valor no manipulado de get_user_name
. ¿Cómo puedo simular métodos de otros paquetes que estoy importando en un espacio de nombres bajo prueba?
Mock
, que se incluye en python3.3 + asunittest.mock
.Respuestas:
Cuando se utiliza el
patch
decorador delunittest.mock
paquete que está no pacheando el espacio de nombres del módulo ha sido importada desde (en este casoapp.my_module.get_user_name
) que está remendándolo en el espacio de nombres bajo pruebaapp.mocking.get_user_name
.Para hacer lo anterior,
Mock
intente algo como lo siguiente:La documentación de la biblioteca estándar incluye una sección útil que describe esto.
fuente
get_user_name
está en un módulo diferente altest_method
. ¿Hay alguna forma de simular algo en un sub_módulo? Lo arreglé de una manera fea abajo.get_user_name
esté en un módulo diferente altest_method
que está importando la funciónapp.mocking
en el mismo espacio de nombres.get_user_name_patch
.Si bien la respuesta de Matti John resuelve su problema (y también me ayudó, ¡gracias!), Sin embargo, sugeriría localizar el reemplazo de la función 'get_user_name' original con la burlada. Esto le permitirá controlar cuándo se reemplaza la función y cuándo no. Además, esto le permitirá realizar varios reemplazos en la misma prueba. Para hacerlo, use la declaración 'con' de una manera bastante similar:
fuente
patch
como decorador o administrador de contexto es específico del caso de uso. Por ejemplo, puede usarlopatch
como decorador para simular un valor para todas las pruebas en una clasexunit
opytest
, mientras que en otros casos es útil tener el control detallado que brinda el administrador de contexto.