簡體   English   中英

在 Python 中調用模擬方法的類的測試實例

[英]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 我了解您的測試代碼,因此您希望確保函數foocreate_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.

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