我目前有以下基本的Python类需要测试:
我创建了一个名为
为了解决这个问题,我已经尝试使用
class Example:
def run_steps(self):
self.steps = 0
while self.steps < 4:
self.step()
def step(self):
# some expensive API call
print("wasting time...")
time.sleep(1000)
self.steps += 1
从上面的代码可以看出,step() 方法包含一个昂贵的 API 调用,因此我希望使用另一个函数来模拟它,该函数避免了昂贵的 API 调用,但仍会增加 self.steps
。我发现这是可能的,方法如下(参见这里):
def mock_step(self):
print("skip the wasting time")
self.steps += 1
# This code works!
def test(mocker):
example = Example()
mocker.patch.object(Example, 'step', mock_step)
example.run_steps()
我创建了一个名为
mock_step(self)
的函数,它避免了API调用,并将原始较慢的step()
方法替换为新的mock_step(self)
函数。
然而,这导致了一个新问题。由于mock_step(self)
函数不是Mock对象,我无法在其上调用任何Mock方法(如assert_called()和call_count())。def test(mocker):
example = Example()
mocker.patch.object(Example, 'step', mock_step)
example.run_steps()
# this line doesn't work
assert mock_step.call_count == 4
为了解决这个问题,我已经尝试使用
wraps
参数将mock_step
包装成一个Mock对象:def test(mocker):
example = Example()
# this doesn't work
step = mocker.Mock(wraps=mock_step)
mocker.patch.object(Example, 'step', step)
example.run_steps()
assert step.call_count == 4
但接着我收到不同的错误信息,指出:mock_step() missing 1 required positional argument: 'self'
。
所以现在我并不确定如何断言run_steps()
中step()
已被调用了确切的4次。
import mock
而不是注入mocker
来测试您的解决方案。但是您似乎修补了类的 方法定义,而不是实际绑定到对象的 方法,这导致了浪费时间的代码被调用。 - Lenormjupytest
中更方便。此外,我想允许使用标准的mock
来允许call_count
,assert_called_xxx
等,而不仅仅是自己计算数量(当然,这也是一种解决方案)。 - MrBean Bremenpip install pytest-mock
就可以了。你的解决方案比我的更好 :) - Lenormjumocker.patch
返回的是被修补对象的 Mock,所以我从来没有想过要做像mocked = mocker.patch.object(Example, 'step')
这样的事情。感谢您的帮助 :) - runoxinabox