![](/img/trans.png)
[英]How can I use Python MonkeyPatch + Mock to assert that a function was called
[英]How to assert that a mock function is called with a generator?
我正在將py.test
與mock
一起用於單元測試。
被測試的一項功能如下所示:
def convert(rows):
rows = (preprocess(r) for r in rows)
return batch_process(True, rows)
在測試中,我將模擬preprocess
和batch_process
。 對於preprocess
,我使用side_effect
來配置多個返回值,每行一個。
我如何斷言傳遞給batch_process
的第二個參數是preprocess
行的生成器表達式?
考慮簡化測試:您需要測試的是,作為生成器遍歷時的第二個參數包含每行的preprocess()
返回的值。
我將概述如何最終編寫它:
from mock import Mock, call
preprocess_sentinels = [Mock() for _ in range(5)]
mock_preprocess.side_effect = preprocess_sentinels
rows = [Mock() for _ in range(5)]
convert(rows)
mock_preprocess.assert_has_calls([call(r) for r in rows])
args, kwargs = mock_batch_process.call_args
assert args[0]
for v, e in zip(args[1], preprocess_sentinels):
assert v == e
當然,您不必嚴格檢查它是否是生成器,但可以檢查convert()
行為。 確切地檢查您是如何實現的(不是按生成器還是按列表)不是測試應該做什么,它是實現的細節而不是行為:您應該編寫在兩種情況下都可以使用的最佳測試。
我已經找到一種檢查方法,但是它有點冗長,但是在我的項目中對我有用
from mock import Mock, patch
from types import GeneratorType
def test():
mock_batch_process = patch('module.calling.batch_process')
mock_preprocess = patch('module.calling.preprocess')
# our test data for rows
rows = ...
convert(rows)
assert mock_batch_process.call_count == 1
args, kwargs = mock_batch_process.call_args
# get an arg that is expected to be a generator, second arg in this case
preprocess_rows = args[1]
# check that our call arg is a generator
assert isinstance(preprocess_rows, GeneratorType)
# check that it contains all expected values
assert list(preprocess_rows) == [mock_preprocess(row) for row in rows]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.