我想在单元测试中修补 Python 中的一个类。主要代码是这样的(mymath.py
):
class MyMath:
def my_add(self, a, b):
return a + b
def add_three_and_two():
my_math = MyMath()
return my_math.my_add(3, 2)
测试类是这样的:
import unittest
from unittest.mock import patch
import mymath
class TestMyMath(unittest.TestCase):
@patch('mymath.MyMath')
def test_add_three_and_two(self, mymath_mock):
mymath_mock.my_add.return_value = 5
result = mymath.add_three_and_two()
mymath_mock.my_add.assert_called_once_with(3, 2)
self.assertEqual(5, result)
unittest.main()
我收到以下错误:
AssertionError: Expected 'my_add' to be called once. Called 0 times.
最后一个断言也会失败:
AssertionError: 5 != <MagicMock name='MyMath().my_add()' id='3006283127328'>
我希望上述测试能够通过。我做错了什么?
更新: 限制:
- 如果可能的话我不会改变测试过的部分。 (我很好奇这是否可能,这就是问题的重点。)
- 如果不可能,那么我希望待测试部分的更改量最小。特别是我想让
my_add()
函数保持非静态。
最佳答案
无需修补整个类,只需修补函数即可。
class TestMyMath(unittest.TestCase):
@patch.object(mymath.MyMath, 'my_add')
def test_add_three_and_two(self, m):
m.return_value = 5
result = mymath.add_three_and_two()
m.assert_called_once_with(3, 2)
self.assertEqual(5, result)
我认为最初的问题是 my_math.my_add
每次使用时都会生成一个新模拟对象;您配置了一个 Mock
的 return_value
属性,但随后检查是否调用了另一个 Mock
实例。至少,使用 patch.object
可确保您尽可能少地干扰原始代码。
关于python - 使用装饰器补丁在 Python 中模拟类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74525368/