python mock-用自己修补方法-缺少1个必需的位置参数



我想修补一个方法,以测试它是否被调用,但同时我不想失去功能,所以我的想法是用自己来修补这个方法:

import unittest
from unittest.mock import Mock, patch

class MyClass():

def foo(self, num):
return num + 2

class myTestClass(unittest.TestCase):
@patch.object(MyClass,'foo', Mock(wraps=MyClass.foo))
def test_foo(self):
my_class = MyClass()
result = my_class.foo(2)
my_class.foo.assert_called_once_with(2)
self.assertEqual(result, 4)

在执行过程中,我得到以下错误:

File "/usr/lib64/python3.6/unittest/mock.py", line 1014, in _mock_call
return self._mock_wraps(*args, **kwargs)
TypeError: foo() missing 1 required positional argument: 'num'

用这种方式打补丁可能吗?可能有一种变通方法

我在这里看到了几个问题:

  1. 您正在修补类,而不是对象;但是测试对象,而不是类
  2. 你在用Mock包装,我觉得这是不对的
  3. 还有一个次要的问题:您将要测试的对象命名为my_class,这很容易被误读

我认为您的算法的正确解决方案可以是:


import unittest
from unittest.mock import Mock, patch

class MyClass():

def foo(self, num):
return num + 2

class myTestClass(unittest.TestCase):
@patch.object(MyClass,'foo', wraps=MyClass.foo)
def test_foo(self, mocked):
obj = MyClass()
result = MyClass.foo(obj, 2)
MyClass.foo.assert_called_once_with(obj, 2)
self.assertEqual(result, 4)

if __name__ == '__main__':
unittest.main()

注意:

  • wraps=MyClass.foo而不是wraps=Mock(...)
  • def test_do(self, mocked)而不是def test_do(self)(将模拟对象传递给方法(
  • MyClass.foo(obj, 2),因为您已经修补了类,而不是对象
  • MyClass.foo.assert_called_once_with(obj, 2),因为您必须检查类方法(已修补(

或者,您可以像本测试中那样修补对象:


def test_foo_object(self):
obj = MyClass()
with patch.object(obj, 'foo', wraps=obj.foo):
result = obj.foo(2)
obj.foo.assert_called_once_with(2)
self.assertEqual(result, 4)

最新更新