簡體   English   中英

Python 2.7 mock / patch:理解assert_called_XYZ()

[英]Python 2.7 mock/patch: understanding assert_called_XYZ()

我對Python和Python中的單元測試比較陌生。 從Java世界我知道模擬的概念,但它似乎與我在Python中看到的有很大不同。

我找到了這個指南,我發現它非常有用: http//www.voidspace.org.uk/python/mock/index.html

但是當我使用模擬的依賴關系編寫我的(更復雜的)測試時,我注意到了一個strage行為。 我決定創建一個簡化的簡單示例,它也不像我預期的那樣工作。

看看這個,結果和我作為評論添加的期望:

import unittest
from mock import patch, Mock, MagicMock

class BasicTest(unittest.TestCase):

    @patch("StringIO.StringIO")
    def testSomethingNotWorkingAsExpected(self, StringIOMock):
        StringIOMock.assert_called_once() # asserts, but why?

    @patch("StringIO.StringIO")
    def testSomethingSomehowWorking(self, StringIOMock):
        # self.instantiateStringIO() # intentionally commented out
        assert StringIOMock.called # does not assert (leading to failure of this test); as expected. If the above line is not commented, this asserts as expected.

    def instantiateStringIO(self):
        import StringIO
        StringIO.StringIO()

為什么assert_called_once()斷言的實例StringIO ,即使它沒有被實例化了嗎? 為什么assert ClassMock.called帶來預期的結果呢?

使用assert not ...斷言一個方法尚未被調用我在這里找到: 斷言函數/方法沒有使用Mock調用 在我的情況下,我通過省略not顛倒了這種模式。

在某處我找到了模式ClassMock.return_value來引用一個實例。 但我理解這是一種在調用Mock之前對其進行管理的方法,而不是作為訪問可能是內部創建的底層代碼的實例的方法。 還是我錯了?

我的環境:

  • Python 2.7.3
  • 模擬0.8.8
  • Fedora 19

可能我對模擬/補丁的理解是錯誤的。 可以請某人在某種程度上解釋一下類模擬的作用以及它是如何工作的嗎?

Edit1:添加輸出

...並在parens中添加釋義以在testSomethingSomehowWorking發表評論

這是輸出:

.F
======================================================================
FAIL: testSomethingSomehowWorking (test_test.BasicTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/mock.py", line 1224, in patched
    return func(*args, **keywargs)
  File "test_test.py", line 15, in testSomethingSomehowWorking
    assert StringIOMock.called # does not assert; as expected
AssertionError

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)

方法assert_called_once不存在,並且它不執行斷言。 它與編寫StringIOMock.assert_foo_bar_does_not_exist()或任何其他方法沒有什么不同。 模擬庫不檢查模擬上調用的方法是否實際存在。

如果使用assert_called_once_with則會按預期失敗。

調用不存在的方法時,可以使用spec參數引發錯誤:

@patch("StringIO.StringIO", spec=StringIO.StringIO)
def testSomethingNotWorkingAsExpected(self, StringIOMock):
    StringIOMock.assert_called_once() # will fail as the method doesn't exist

暫無
暫無

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

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