我有一个python文件a.py
,其中包含两个类A
和B
。
class A(object):
def method_a(self):
return "Class A method a"
class B(object):
def method_b(self):
a = A()
print a.method_a()
我想通过模拟A
来单元测试B
类中的method_b
。以下是用于此目的的文件testa.py
的内容:
import unittest
import mock
import a
class TestB(unittest.TestCase):
@mock.patch('a.A')
def test_method_b(self, mock_a):
mock_a.method_a.return_value = 'Mocked A'
b = a.B()
b.method_b()
if __name__ == '__main__':
unittest.main()
我期望在输出中得到Mocked A
。但是我得到的是:
<MagicMock name='A().method_a()' id='4326621392'>
我哪里做错了?
当您使用@mock.patch('a.A')
时,您正在用mock_a
替换测试代码中的A
类。
然后在B.method_b
中设置a = A()
,现在是a = mock_a()
-即a
是mock_a
的return_value
。由于您没有指定此值,因此它是常规的MagicMock
;这也没有配置,所以当调用它的方法时,您会得到默认响应(另一个MagicMock
)。
mock_a
的return_value
以具有适当的方法,您可以这样做:
mock_a().method_a.return_value = 'Mocked A'
# ^ note parentheses
或者更明确地说:
mock_a.return_value.method_a.return_value = 'Mocked A'
您的代码将在a = A
的情况下工作(分配类,而不是创建实例),因为a.method_a()
将触发您的模拟方法。
在模拟对象的情况下,我使用以下语法:
@mock.patch.object(
a.A,
'method_a',
lambda a: "Mocked A")
def test_method_b(self):
b = a.B()
b.method_b()
在这种情况下,method_a是由lambda函数模拟的。
在我的例子中,我的return_value是这个{"key1": "value1"}
。因此,在应用补丁之前,我需要使用dict()
进行强制转换。
:
@fixture
def mock_something(mocker: MockFixture, request: SubRequest) -> MagicMock:
method_to_mock = f"your_module.YourClass.some_method"
return_value = dict(request.param)
if isinstance(return_value, Exception):
return mocker.patch(method_to_mock, side_effect=return_value)
return mocker.patch(method_to_mock, return_value=return_value)