我正在尝试模拟依赖方法的返回值,但是返回值在使用return_value
和向mock.patch
添加附加参数之间有所不同。请帮我找出原因。我尝试在线搜索,但找不到答案。
library / abc.py:
from tools.operating_system import os_name
class ABC(object):
def get_os_info(self):
return os_name()
tools / operating_system.py:
import os
def os_name():
return os.name
library / 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有同样的问题
答案 0 :(得分:0)
请参阅mock.patch的文档:致电时
with mock.patch('tools.operating_system.os.name', 'test')
您正在这样做:
with mock.patch('tools.operating_system.os.name', NEW='test')
您将os.name
替换为字符串test
,以便按预期工作。
致电时
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
。
最后一点个人喜好:我更喜欢注入依赖而不是尽可能地打补丁,例如,参见文章"Every mock.patch() is a little smell"。