[英]python - mock - class method mocked but not reported as being called
[英]Test instance of class that mocked method is called from in Python
我正在模擬一個類的方法,並想測試調用該方法的類的實例,以測試我的函數的創建部分是否按預期工作。
在我的特殊情況下, do_stuff
嘗試將bar_instance
寫入 Excel 文件,我不希望發生這種情況,即
def create_instance(*args):
return Bar(*args)
class Bar():
def __init__(self, *args):
self.args = args
def do_stuff(self):
pass
def foo(*args):
bar_instance = create_instance(*args)
bar_instance.do_stuff()
然后在測試文件中
from unittest import TestCase
from unittest.mock import patch
from path.to.file import foo
class TestFoo(TestCase):
@patch('path.to.file.Bar.do_stuff')
def test_foo(self, mock_do_stuff):
test_args = [1]
_ = foo(*test_args)
# Test here the instance of `Bar` that `mock_do_stuff` was called from
# Something like
actual_args = list(bar_instance.args)
self.assertEqual(test_args, actual_args)
在foo(*test_args)
運行后,我在測試函數中放置了一個中斷,但是從訪問它被調用的Bar
實例的foo(*test_args)
不到任何方法,並且有點卡住了。 我不想在代碼中進一步模擬Bar
,因為我想確保正在創建正確的Bar
實例。
在您的代碼示例中,可能需要測試三件事:函數create_instance
、類Bar
和函數foo
。 我了解您的測試代碼,因此您希望確保函數foo
在create_instance
返回的實例上調用 do_stuff 。
由於原始create_instance
函數可以控制創建的實例,因此您的問題的解決方案是模擬create_instance
以便您的測試獲得對移交給 foo 的對象的控制權:
import unittest
from unittest import TestCase
from unittest.mock import patch, MagicMock
from SO_60624698 import foo
class TestFoo(TestCase):
@patch('SO_60624698.create_instance')
def test_foo_calls_do_stuff_on_proper_instance (
self, create_instance_mock ):
# Setup
Bar_mock = MagicMock()
create_instance_mock.return_value = Bar_mock
# Exercise
foo(1, 2, 3) # args are irrelevant
# Verify
Bar_mock.do_stuff.assert_called()
if __name__ == '__main__':
unittest.main()
此外,您可能還想測試foo
將參數正確傳遞給create_instance
。 這可以作為單獨的測試來實現:
...
@patch('SO_60624698.create_instance')
def test_foo_passes_arguments_to_create_instance (
self, create_instance_mock ):
# Setup
create_instance_mock.return_value = MagicMock()
# Exercise
foo(1, 22, 333)
# Verify
create_instance_mock.assert_called_with(1, 22, 333)
當然,為了完成對象生成的整個測試,您可以直接測試create_instance
,方法是調用它並檢查返回的Bar
實例是否正確使用了它的參數來構建Bar
實例。
當patch
返回Mock 的一個實例(或者實際上是 MagicMock,但它從其基礎 - Mock 繼承相關方法)時,您可以使用assert_called_with方法,它應該可以解決問題。 請注意,此方法對args
/ kwargs
敏感 - 您必須斷言完全相同的調用。
另一個注意事項:在這里使用patch.object而不是patch
可能是更好的做法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.