我有一个要在单元测试中打补丁的类。
class OriginalClass():
def method_a():
# do something
def method_b():
# do another thing
现在我创建了另一个类来对其进行修补,因此用于对其进行修补的代码就像
class MockClass(OriginalClass):
def method_a():
# This will override the original method and return custom response for testing.
patcher = patch('OriginalClass', new=MockClass)
mock_instance = patcher.start()
这完全符合我的期望,我可以返回单元测试所需的任何响应。
现在这个问题是当我想验证单元测试中使用正确参数调用的方法时。 我尝试过
mock_instance.method_a.assert_called_once()
但是它失败,并显示错误AttributeError: 'function' object has no attribute 'assert_called_once'
。
如何在这里测试方法调用?
答案 0 :(得分:0)
AttributeError:“函数”对象没有属性“ assert_drawn_once”。
创建模拟对象后,就不存在method_a
,您必须在断言之前调用一次m.method_a()
。
m = mock.create_autospec(OriginalClass)
m.method_a()
m.method_a.assert_called_once()
修补整个类的模拟
我把它当作整个类及其所有方法的模拟,我从这里举一个例子 https://docs.python.org/3.3/library/unittest.mock-examples.html
对每个测试方法都应用相同的补丁,这是我的示例,为每个方法和每个测试将整个Primary类作为MockPrimay进行补丁,可以为所需的方法添加setup or SetupClass
,即使整个类都被模拟了,但并非测试中要使用的所有方法。
from tests.lib.primary_secondary import Secondary
@mock.patch('tests.lib.primary_secondary.Primary')
class TestSecondaryMockPrimary(unittest.TestCase):
def test_method_d(self, MockPrimary):
MockPrimary().process()
MockPrimary().process.return_value = 1
oc = Secondary()
self.assertEqual(oc.method_d(), 1)
import tests
self.assertIs(tests.lib.primary_secondary.Primary, MockPrimary)
此考试的辅助考试需要主考试
class Primary(object):
def __init__(self, param):
self._param = param
def process(self):
if self._param == 1:
self._do_intermediate_process()
self._do_process()
class Secondary(object):
def __init__(self):
self.scl = Primary(1)
def method_d(self):
return self.scl.process
答案 1 :(得分:0)
我认为wraps
在这里可能会有用:
from unittest.mock import patch
class Person:
name = "Bob"
def age(self):
return 35
class Double(Person):
def age(self):
return 5
with patch('__main__.Person', wraps=Double()) as mock:
print(mock.name) # mocks data
print(mock.age()) # runs real methods, but still spies their calls
mock.age.assert_not_called()
输出:
<MagicMock name='Person.name' id='139815250247536'>
5
...
raise AssertionError(msg)
AssertionError: Expected 'age' to not have been called. Called 1 times.
Calls: [call()].