Eu quero entender como @patch
uma função de um módulo importado.
É aqui que estou até agora.
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()
Isso não funciona como eu esperava. O módulo "corrigido" simplesmente retorna o valor desbloqueado de get_user_name
. Como faço para simular métodos de outros pacotes que estou importando para um namespace em teste?
Mock
, que está incluída em python3.3 + asunittest.mock
.Respostas:
Quando você está usando o
patch
decorador dounittest.mock
pacote, você não está corrigindo o namespace do qual o módulo é importado (neste casoapp.my_module.get_user_name
), você o está corrigindo no namespace em testeapp.mocking.get_user_name
.Para fazer o acima,
Mock
tente algo como o seguinte:A documentação da biblioteca padrão inclui uma seção útil que descreve isso.
fonte
get_user_name
está em um módulo diferente detest_method
. Existe uma maneira de simular algo em um sub_module? Eu consertei de uma maneira feia abaixo.get_user_name
esteja em um módulo diferente daquele em quetest_method
você está importando a função,app.mocking
eles estão no mesmo namespace.get_user_name_patch
.Embora a resposta de Matti John resolva seu problema (e me ajude também, obrigado!), Gostaria, no entanto, de sugerir localizar a substituição da função 'get_user_name' original pela função simulada. Isso permitirá que você controle quando a função é substituída e quando não é. Além disso, isso permitirá que você faça várias substituições no mesmo teste. Para fazer isso, use a instrução 'com' de uma maneira bastante semelhante:
fonte
patch
como decorador ou gerenciador de contexto é específico para o caso de uso. Por exemplo, você pode usarpatch
como um decorador para simular um valor para todos os testes em uma classexunit
ou,pytest
enquanto em outros casos é útil ter o controle refinado fornecido pelo gerenciador de contexto.