python中MagicMock的子类化
我有一个需要修补的类,其工作原理与此类似python中MagicMock的子类化,python,python-3.x,mocking,python-unittest,python-mock,Python,Python 3.x,Mocking,Python Unittest,Python Mock,我有一个需要修补的类,其工作原理与此类似 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传入的数据。我想到像这样子类化M
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)
但是我不太明白如何在实际的测试用例中应用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)
我知道我可以将plain
MagicMock
与autospec=True
一起使用,然后覆盖每个方法的返回值,但是如果有一个模拟类,我就可以用它一次性替换生产类,那就太好了。关键位是,必须在mock方法中访问成员变量self.\u query
,同时在构造函数中对其进行初始化(就像生产类一样) 关于您的基本问题答案是使用new\u callable
参数:
如果您需要对<代码> MOCKFOO init调用添加一些参数,请考虑在<代码>修补程序中使用的每个参数都将是PasSit到模拟构造函数(<代码> Mokfoo在您的情况下)。
如果您需要为生产类创建一个包装器,那么您可能找错了地方:mock不是包装器当你模拟某些东西时,你并不想知道你的模拟是如何工作的,而是想知道你的代码是如何使用它的,以及你的代码是如何对模拟对象做出反应的。我认为这不起作用,因为在某种程度上你需要区分真实的方法/属性和模拟的方法/属性。像“called”和“return_value”这样的东西是mock的一部分,所以将它们添加到生产类的修改实例中是不可行的。我认为最好按照您所说的那样,模拟您需要的内容,并可能添加一些帮助程序代码。
with patch('x.Foo', new_callable=MockFoo) as mock_foo:
# run test code
self.assertTrue(mock_foo.called)
self.assertEqual(mock_foo.wait.return_value, 20)