簡體   English   中英

unittest.mock.patch:上下文管理器vs unittest中的setUp / tearDown

[英]unittest.mock.patch: Context manager vs setUp/tearDown in unittest

似乎有兩種使用unittest.mock.patch的方法 :一種更好的方法嗎?

使用上下文管理器和with語句:

class MyTest(TestCase):
    def test_something(self):
        with patch('package.module.Class') as MockClass:
            assert package.module.Class is MockClass

或從設置和tearDown / cleanup調用啟動和停止:

class MyTest(TestCase):
    def setUp(self):
        patcher = patch('package.module.Class')
        self.MockClass = patcher.start()
        self.addCleanup(patcher.stop)

    def test_something(self):
        assert package.module.Class is self.MockClass

上下文管理器版本的代碼較少,因此易於爭論。 我有什么理由偏愛使用TestCase setUp / tearDown基礎結構嗎?

setUp更喜歡修補的主要原因是,如果您有多個需要對該類進行修補的測試。 在這種情況下,您需要在每個測試中復制with語句。

如果您只有一個需要補丁的測試,那么我寧願使用with語句以提高可讀性。

還有第三種使用它的方法,作為裝飾器:

class MyTest(testcase):

    @unittest.mock.patch('package.module.Class')
    def test_something(self):
        assert package.module.Class is self.MockClass

這甚至是更少的代碼,但是可能不相關。

有一些注意事項:(1)(如babbageclunk所指出),如果您將需要重用補丁,那么在setUp構造一個簡單而乏味的調用是最好的,並且易於閱讀。 (2)如果您想創建任何元編程工具,以便在運行測試時可以打開或關閉修補程序,那么裝飾器方法將為您省去很多麻煩。 在這種情況下,您可以編寫其他修飾符,或使用全局變量(ick)控制是否將補丁修飾符應用於測試功能。 如果它們嵌入在函數定義中,則如果要在運行測試時關閉修補程序,則必須手動處理它們。 您可能希望這樣做的一個簡單原因只是在沒有補丁的情況下運行測試,從而導致大量失敗,並觀察尚未實現的部分(實際上,您用於元編程補丁的裝飾器可能會捕獲這些問題並打印出不錯的NotImplemented例外,甚至生成包含此類內容的報告)。 可能有更多的原因想要更好地控制在給定時間在測試套件中是否(以及在何種程度上)修補程序被“分發”。

裝飾器方法也很不錯,因為(a)它允許您以該函數之外的方式隔離哪些補丁進入了哪個測試函數,而無需將其提交給setUp ;以及(b)使其非常清楚給定功能需要給定補丁的閱讀器。

在這種情況下,上下文管理器版本似乎沒有很多好處,因為它幾乎不比裝飾器版本更具可讀性。 但是,如果確實只使用一種情況,或者使用的情況很少,那么上下文管理器版本就可以了。

暫無
暫無

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

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