问题:Python从导入的模块中模拟函数
我想了解如何@patch
从导入的模块执行功能。
这是我到目前为止的位置。
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"
测试/模拟测试.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
。如何模拟要导入到被测命名空间中的其他包中的方法?
回答 0
当您patch
从unittest.mock
包中使用装饰器时,您未在修补命名空间,而是从(在这种情况下app.my_module.get_user_name
)导入模块,而是在被测试的命名空间中对其进行修补app.mocking.get_user_name
。
为此,请Mock
尝试以下类似方法:
from mock import patch
from app.mocking import test_method
class MockingTestTestCase(unittest.TestCase):
@patch('app.mocking.get_user_name')
def test_mock_stubs(self, test_patch):
test_patch.return_value = 'Mocked This Silly'
ret = test_method()
self.assertEqual(ret, 'Mocked This Silly')
标准库文档中包含一个有用的部分对此进行了描述。
回答 1
尽管Matti John的答案解决了您的问题(也为我提供了帮助,谢谢!),但是,我建议将本地的“ get_user_name”函数替换为模拟的函数。这将允许您控制何时替换功能以及何时不替换功能。同样,这将允许您在同一测试中进行多次替换。为此,请以类似的方式使用“ with”语句:
from mock import patch
class MockingTestTestCase(unittest.TestCase):
def test_mock_stubs(self):
with patch('app.mocking.get_user_name', return_value = 'Mocked This Silly'):
ret = test_method()
self.assertEqual(ret, 'Mocked This Silly')