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"

测试/ 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的未模拟值。如何模拟正在导入到测试中的名称空间中的其他包中的方法?

130320 次浏览

当你使用unittest.mock包中的patch装饰器时,你是在正在测试的名称空间中修补它(在这种情况下是app.mocking.get_user_name),而不是函数导入的命名空间(在这种情况下是app.my_module.get_user_name)。

要完成你用@patch描述的事情,尝试如下所示:

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')

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

虽然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')

除了Matti John的解决方案,你还可以在app/mocking.py中导入module而不是function。

# from app.my_module import get_user_name
from app import my_module


def test_method():
return my_module.get_user_name()


if __name__ == "__main__":
print "Starting Program..."
test_method()