模拟 Class 和断言方法调用
Mocked Class & Asserting Method Calls
难以理解如何模拟 class 并能够断言它的方法是用一些参数调用的。当我断言调用时,我得到一个 "Not called" 断言但是,我可以在 mock_calls
属性中看到方法调用。
sandbox/module.py
class Subject(object):
def __init__(self):
pass
def run(self, *args, **kwargs):
reference = Reference(*args, **kwargs)
reference.method_a(*args)
class Reference(object):
def __init__(self, *args, **kwargs):
pass
def method_a(self, *args):
pass
test.py
import unittest
from unittest import mock
from sandbox.module import Subject
class TestSandbox(unittest.TestCase):
@mock.patch('sandbox.module.Reference')
def test_method_calls(self, mock_reference):
subject = Subject()
subject.run(1, 2, 3, x=44, y=55, z=66)
mock_reference.assert_called_with(1, 2, 3, x=44, y=55, z=66)
mock_reference.method_a.assert_called_with(1, 2, 3)
结果是
AssertionError: Expected call: method_a(1, 2, 3)
Not called
mock_reference.mock_calls
的值为
[
call(1, 2, 3, x=44, y=55, z=66),
call().method_a(1, 2, 3)
]
如果我以 call().method_a
访问调用,我可以访问方法详细信息,但是 mock_calls
会添加一个项目 call()
。这可能会以一种我不期望的方式改变 assert_called_once_with
,而且感觉不太对。此外,如果使用 autospec=True
我需要再次传递参数。像 mock_reference.call.method_a
那样只使用 call
也不起作用。
访问call().method_a.mock_calls
时mock_calls
的输出
mock_reference().method_a.mock_calls
[
call(1, 2, 3, x=44, y=55, z=66),
call().method_a(1, 2, 3),
call()
]
mock_reference.assert_called_once_with(1, 2, 3)
AssertionError: Expected 'Reference' to be called once. Called 2 times.
您模拟了一个 class,但在实例上调用了第二个方法。变化
mock_reference.method_a.assert_called_with(1, 2, 3)
至
mock_reference.return_value.method_a.assert_called_with(1, 2, 3)
难以理解如何模拟 class 并能够断言它的方法是用一些参数调用的。当我断言调用时,我得到一个 "Not called" 断言但是,我可以在 mock_calls
属性中看到方法调用。
sandbox/module.py
class Subject(object):
def __init__(self):
pass
def run(self, *args, **kwargs):
reference = Reference(*args, **kwargs)
reference.method_a(*args)
class Reference(object):
def __init__(self, *args, **kwargs):
pass
def method_a(self, *args):
pass
test.py
import unittest
from unittest import mock
from sandbox.module import Subject
class TestSandbox(unittest.TestCase):
@mock.patch('sandbox.module.Reference')
def test_method_calls(self, mock_reference):
subject = Subject()
subject.run(1, 2, 3, x=44, y=55, z=66)
mock_reference.assert_called_with(1, 2, 3, x=44, y=55, z=66)
mock_reference.method_a.assert_called_with(1, 2, 3)
结果是
AssertionError: Expected call: method_a(1, 2, 3)
Not called
mock_reference.mock_calls
的值为
[
call(1, 2, 3, x=44, y=55, z=66),
call().method_a(1, 2, 3)
]
如果我以 call().method_a
访问调用,我可以访问方法详细信息,但是 mock_calls
会添加一个项目 call()
。这可能会以一种我不期望的方式改变 assert_called_once_with
,而且感觉不太对。此外,如果使用 autospec=True
我需要再次传递参数。像 mock_reference.call.method_a
那样只使用 call
也不起作用。
访问call().method_a.mock_calls
时mock_calls
的输出
mock_reference().method_a.mock_calls
[
call(1, 2, 3, x=44, y=55, z=66),
call().method_a(1, 2, 3),
call()
]
mock_reference.assert_called_once_with(1, 2, 3)
AssertionError: Expected 'Reference' to be called once. Called 2 times.
您模拟了一个 class,但在实例上调用了第二个方法。变化
mock_reference.method_a.assert_called_with(1, 2, 3)
至
mock_reference.return_value.method_a.assert_called_with(1, 2, 3)