簡體   English   中英

如何斷言用生成器調用了模擬函數?

[英]How to assert that a mock function is called with a generator?

我正在將py.testmock一起用於單元測試。

被測試的一項功能如下所示:

def convert(rows):
    rows = (preprocess(r) for r in rows)
    return batch_process(True, rows)

在測試中,我將模擬preprocessbatch_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM