模拟 类 和断言方法调用的正确方法
Proper way to mock classes and assert on calls to methods
我正在尝试为 Bar
编写调用 Foo
方法 read()
的单元测试。我在 setUp()
中添加了补丁命令,因为其他测试也会使用这个补丁。
问题
如何检查 read()
函数是否使用我期望的参数调用?
代码
foo.py
class Foo(object):
def __init__(self):
self.table = {'foo': 1}
def read(self, name):
return self.table[name]
bar.py
import foo
class Bar(object):
def act(self):
a = foo.Foo()
return a.read('foo')
test_bar.py
import bar
import unittest
from mock import patch
class TestBar(unittest.TestCase):
def setUp(self):
self.foo_mock = patch('bar.foo.Foo', autospec=True).start()
self.addCleanup(patch.stopall)
def test_can_call_foo_with_correct_arguments(self):
a = bar.Bar()
a.act()
self.foo_mock.read.assert_called_once_with('foo')
输出
python -m unittest discover
F
======================================================================
FAIL: test_can_call_foo_with_correct_arguments (test_bar.TestBar)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/test_dir/test_bar.py", line 12, in test_can_call_foo_with_correct_arguments
self.foo_mock.read.assert_called_once_with('foo')
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 845, in assert_called_once_with
raise AssertionError(msg)
AssertionError: Expected to be called once. Called 0 times.
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
read
是 Foo
的 个实例 上的方法。您想要检查模拟 return_value
以访问该实例。毕竟,您通过 调用 foo.Foo()
:
创建实例
foo_instance = self.foo_mock.return_value
foo_instance.read.assert_called_once_with('foo')
请注意,您正在修补 foo.Foo
; using bar.foo.Foo
是同一个对象,但是指定它的一种迂回方式。
模拟有很多陷阱,这就是为什么 I wrote a helper library 为我生成断言。
要使用它,你应该在a.act()
之后添加以下行:
import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(mock=self.foo_mock, name='self.foo_mock'))
这会输出这些行:
assert 1 == self.foo_mock.call_count
self.foo_mock.assert_called_once_with()
self.foo_mock.return_value.read.assert_called_once_with('foo')
生成前两个是因为 foo 是 class 实例化的。第三行就是你原来要找的那行。
所以不要再猜测了,要有条不紊地使用 mock-generator。
我正在尝试为 Bar
编写调用 Foo
方法 read()
的单元测试。我在 setUp()
中添加了补丁命令,因为其他测试也会使用这个补丁。
问题
如何检查 read()
函数是否使用我期望的参数调用?
代码
foo.py
class Foo(object):
def __init__(self):
self.table = {'foo': 1}
def read(self, name):
return self.table[name]
bar.py
import foo
class Bar(object):
def act(self):
a = foo.Foo()
return a.read('foo')
test_bar.py
import bar
import unittest
from mock import patch
class TestBar(unittest.TestCase):
def setUp(self):
self.foo_mock = patch('bar.foo.Foo', autospec=True).start()
self.addCleanup(patch.stopall)
def test_can_call_foo_with_correct_arguments(self):
a = bar.Bar()
a.act()
self.foo_mock.read.assert_called_once_with('foo')
输出
python -m unittest discover
F
======================================================================
FAIL: test_can_call_foo_with_correct_arguments (test_bar.TestBar)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/test_dir/test_bar.py", line 12, in test_can_call_foo_with_correct_arguments
self.foo_mock.read.assert_called_once_with('foo')
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 845, in assert_called_once_with
raise AssertionError(msg)
AssertionError: Expected to be called once. Called 0 times.
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
read
是 Foo
的 个实例 上的方法。您想要检查模拟 return_value
以访问该实例。毕竟,您通过 调用 foo.Foo()
:
foo_instance = self.foo_mock.return_value
foo_instance.read.assert_called_once_with('foo')
请注意,您正在修补 foo.Foo
; using bar.foo.Foo
是同一个对象,但是指定它的一种迂回方式。
模拟有很多陷阱,这就是为什么 I wrote a helper library 为我生成断言。
要使用它,你应该在a.act()
之后添加以下行:
import mock_autogen.generator
print(mock_autogen.generator.generate_asserts(mock=self.foo_mock, name='self.foo_mock'))
这会输出这些行:
assert 1 == self.foo_mock.call_count
self.foo_mock.assert_called_once_with()
self.foo_mock.return_value.read.assert_called_once_with('foo')
生成前两个是因为 foo 是 class 实例化的。第三行就是你原来要找的那行。
所以不要再猜测了,要有条不紊地使用 mock-generator。