Python从导入的模块中嘲弄一个函数

我想了解如何从一个导入的模块中@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" 

testing/ 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() 

这不符合我的预期。 “patched”模块只是简单地返回get_user_name的unmocked值。 我如何从其他包中导入到被测命名空间中的方法进行模拟?

当您使用unittest.mock包中的patch修饰符时,您修补从模块导入的名称空间(在本例中为app.my_module.get_user_name ),而是将其修补到testing下的名称空间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') 

标准的库文档包括一个有用的部分描述这一点。

虽然马蒂约翰的答案解决了你的问题(也帮助了我,谢谢!),但是,我会build议本地化replace原来的'get_user_name'函数与嘲笑的。 这将允许您控制何时更换function以及何时不更换function。 此外,这将允许您在同一个testing中做几个replace。 为了做到这一点,请以相当相似的方式使用'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')