簡體   English   中英

如何使用 mock.patch 模擬生成器

[英]How to mock generators with mock.patch

我瀏覽了https://docs.python.org/3/library/unittest.mock-examples.html頁面,我看到他們列出了一個關於如何模擬生成器的示例

我有一個代碼,我在其中調用生成器來給我一組保存為字典的值。 我想在我的單元測試中模擬對這個生成器的調用。

我已經編寫了以下代碼,但它不起作用。

我哪里出錯了?

In [7]: items = [(1,'a'),(2,'a'),(3,'a')]

In [18]: def f():
    print "here"
    for i in [1,2,3]:
        yield i,'a'

In [8]: def call_f():
   ...:     my_dict = dict(f())
   ...:     print my_dict[1]
   ...: 

In [9]: call_f()
"here"
a

In [10]: import mock


In [18]: def test_call_f():
    with mock.patch('__main__.f') as mock_f:
        mock_f.iter.return_value = items
        call_f()
   ....: 

In [19]: test_call_f()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-19-33ca65a4f3eb> in <module>()
----> 1 test_call_f()

<ipython-input-18-92ff5f1363c8> in test_call_f()
      2     with mock.patch('__main__.f') as mock_f:
      3         mock_f.iter.return_value = items
----> 4         call_f()

<ipython-input-8-a5cff08ebf69> in call_f()
      1 def call_f():
      2     my_dict = dict(f())
----> 3     print my_dict[1]

KeyError: 1

改變這一行:

mock_f.iter.return_value = items

對此:

mock_f.return_value = iter(items)

我有另一種方法:

mock_f.__iter__.return_value = [items]

這樣您就可以真正模擬迭代器返回的值。

即使您正在模擬可迭代且具有方法的復雜對象(我的情況),這種方法也有效。

我嘗試了選擇的答案,但在我的情況下不起作用,只有在我嘲笑我解釋的方式時才起作用

維姆斯回答

mock_f.return_value = iter(items)

只要你的模擬只被調用一次就可以工作。 在單元測試中,我們可能經常想用不同的參數多次調用一個函數或方法。 在這種情況下這將失敗,因為在第一次調用時迭代器將耗盡,因此在第二次調用時它會立即引發StopIteration異常。 通過Alexandre Paes 的回答,當我的模擬來自unittest.mock.patch時,我得到了一個AttributeError: 'function' object has no attribute '__iter__'

作為替代方案,我們可以創建一個“假”迭代器並將其分配為side_effect

@unittest.mock.patch("mymod.my_generator", autospec=True):
def test_my_func(mm):
    from mymod import my_func
    def fake():
        yield from [items]
    mm.side_effect = fake
    my_func()  # which calls mymod.my_generator
    my_func()  # subsequent calls work without unwanted memory from first call

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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