Я хочу понять, как выполнить @patch
функцию из импортированного модуля.
Вот где я пока нахожусь.
Приложение / 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()
Приложение / my_module / __ init__.py:
def get_user_name():
return "Unmocked User"
тест / 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()
Это не работает так, как я ожидал. «Патченный» модуль просто возвращает разблокированное значение get_user_name
. Как имитировать методы из других пакетов, которые я импортирую в тестируемое пространство имен?
Mock
, которая включена в python3.3 + asunittest.mock
.Ответы:
Когда вы используете
patch
декоратор изunittest.mock
пакета, вы не исправляете пространство имен, из которого импортируется модуль (в данном случаеapp.my_module.get_user_name
), вы исправляете его в тестируемом пространстве именapp.mocking.get_user_name
.Чтобы сделать это,
Mock
попробуйте что-то вроде следующего:В документации стандартной библиотеки есть полезный раздел, описывающий это.
источник
get_user_name
находится в другом модуле, чемtest_method
. Есть ли способ поиздеваться над чем-то в sub_module? Я исправил это некрасивым способом ниже.get_user_name
находятся в другом модуле, чемtest_method
поскольку вы импортируете функцию,app.mocking
они находятся в том же пространстве имен.get_user_name_patch
.Хотя ответ Матти Джона решает вашу проблему (и помог мне тоже, спасибо!), Я бы, однако, предложил локализовать замену исходной функции get_user_name на поддельную. Это позволит вам контролировать, когда функция заменяется, а когда нет. Кроме того, это позволит вам выполнить несколько замен в одном тесте. Для этого используйте условие 'with' довольно похожим образом:
источник
patch
в качестве декоратора или диспетчера контекста, зависит от варианта использования. Например, вы можете использоватьpatch
в качестве декоратора для имитации значения для всех тестов в классеxunit
или, вpytest
то время как в других случаях полезно иметь мелкозернистый контроль, предоставляемый диспетчером контекста.