![](/img/trans.png)
[英]How does the (undocumented) return_value argument for unittest.mock.patch work?
[英]Why does python mock.patch work differently when second patch argument is used vs return_value?
我试图模拟一个依赖方法的返回值,但返回值在使用return_value
和向mock.patch
添加一个额外的参数之间是不同的。 请帮我弄清楚原因。 我尝试在线搜索,但找不到答案。
库/ abc.py:
from tools.operating_system import os_name
class ABC(object):
def get_os_info(self):
return os_name()
工具/ operating_system.py:
import os
def os_name():
return os.name
库/ test_abc.py:
from unittest import TestCase, mock
from library.abc import ABC
class TestMain(TestCase):
# This works because the name method returns `test`
def test_mocking_os_name(self):
with mock.patch('tools.operating_system.os.name', 'test'):
abc = ABC()
res = abc.get_os_info()
self.assertEqual(res, 'test')
# The test fails because the name method returns `<MagicMock name='name' id='4515046400'>`
def test_mocking_os_name(self):
with mock.patch('tools.operating_system.os.name') as mock_name:
mock_name.return_value = 'test'
abc = ABC()
res = abc.get_os_info()
self.assertEqual(res, 'test')
注意:这个例子有点人为,因为我可以模拟os_name
方法。 这不是主要问题。 我正在尝试学习python测试模拟,我希望能够模拟os.name
。 谢谢! 这适用于Python 3.7.2但我在Python 2.7.15中遇到了同样的问题
请参阅mock.patch的文档:当您调用它时
with mock.patch('tools.operating_system.os.name', 'test')
您正在执行此操作:
with mock.patch('tools.operating_system.os.name', NEW='test')
您将用字符串test
替换os.name
,这样可以正常工作。
当你打电话给这个
with mock.patch('tools.operating_system.os.name') as mock_name:
您正在执行此操作:
with mock.patch('tools.operating_system.os.name', NEW=DEFAULT) as mock_name:
您将NEW
保留为NEW=DEFAULT
因此os.name
设置为MagicMock
对象(如文档所述)。 设置mock_name.return_value='test'
不起作用,因为你没有在代码中的任何地方调用函数os.name()
,当然你也不应该这样,因为os.name
是一个字符串而不是一个函数。
就像您说的那样,在实际代码中,您需要修补os_name
函数而不是os.name
:
def test_patching_os_name(self):
with mock.patch('library.abc.os_name') as mock_os_name:
mock_os_name.return_value = 'test'
abc = ABC()
res = abc.get_os_info()
self.assertEqual(res, 'test')
此测试不依赖于os_name
函数的内部实现 。 如果ABC
类的正确行为依赖于os_name
总是返回os.name
(这是测试所断言的),那么该类也可以使用os.name
本身而不依赖于tools.operating_system
。
最终,我有一点个人偏爱:我更喜欢注入依赖项,而不是尽可能地打补丁,例如,参见文章“每个嘲笑.patch()都有点气味” 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.