【发布时间】:2015-04-07 11:53:20
【问题描述】:
我有一个需要修补的类,它的工作原理与此类似
class Foo(object):
def __init__(self, query):
self._query = query
def do_stuff(self):
# do stuff with self._query
我将如何为 Foo 设置一个模拟类
foo = MockFoo(query)
foo.do_stuff()
返回一个模拟结果,但仍考虑为query 传入的数据。我想过像这样子类化MagicMock
class MockFoo(MagicMock):
def __init__(self, query, *args, **kwargs):
super(MagicMock, self).__init__(*args, **kwargs)
self._query
def do_stuff(self):
mock_result = self._query * 10
return MagicMock(return_value=mock_result)
但我不太清楚如何在实际的 TestCase 中应用 patch 以使用 MockFoo 而不是 MagicMock。我需要能够编写类似的测试。
with patch('x.Foo') as mock_foo:
# run test code
self.assertTrue(mock_foo.called)
self.assertEqual(mock_foo.wait.return_value, 20)
我知道我可以使用普通的MagicMock 和autospec=True 或其他东西并覆盖每个方法的返回值,但是如果有一个模拟类可以用来替换生产类就好了一气呵成。关键是,必须在模拟方法中访问成员变量self._query,同时在构造函数中对其进行初始化(就像生产类一样)。
【问题讨论】:
-
我认为这行不通,因为在某种程度上,您需要区分真实方法/属性和模拟方法/属性。诸如“调用”和“返回值”之类的东西是模拟的一部分,因此将它们添加到生产类的修改实例中是不可行的。我认为最好通过模拟你需要的东西并可能添加一些帮助代码来做到这一点。
标签: python python-3.x mocking python-unittest python-mock