[英]Python mock - mocking class method that modifies class attributes
我目前有以下要測試的基本 Python class :
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 調用,因此我想用另一個 function 模擬它,以避免昂貴的 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)
的 function 來避免 API 調用,然后我使用新的mock_step(self)
ZC1C425268E68385D14AB5074C17A 修補原始的慢step()
方法。
然而,這導致了一個新的問題。 由於mock_step(self)
function 不是 Mock object,因此我無法在其上調用任何 Mock 方法(例如 assert_call() 和 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 object 包裝mock_step
:
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'
。
因此,從這個階段開始,我不確定如何斷言step()
在run_steps()
中被准確地調用了 4 次。
有幾種解決方案,最簡單的可能是使用具有副作用的標准模擬:
def mock_step(self):
print("skip the wasting time")
self.steps += 1
def test_step(mocker):
example = Example()
mocked = mocker.patch.object(Example, 'step')
mocked.side_effect = lambda: mock_step(example)
example.run_steps()
assert mocked.call_count == 4
side_effect
可以采用可調用對象,因此您可以同時使用標准模擬和修補方法。
import unittest.mock as mock
from functools import partial
def fake_step(self):
print("faked")
self.steps += 1
def test_api():
api = Example()
with mock.patch.object(api, attribute="step", new=partial(fake_step, self=api)):
# we need to use `partial` to emulate that a real method has its `self` parameter bound at instantiation
api.run_steps()
assert api.steps == 4
正確輸出"faked"
4 次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.