2014-09-29 58 views
3

似乎有2種使用方法unittest.mock.patch:是更好的方法嗎?unittest.mock.patch:上下文管理器vs setUp/tearDown in unittest

使用上下文管理器,並與聲明:

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

或致電開始從安裝和拆卸/清理停止:

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基礎設施?

+0

可能的重複[在python中,是否有一個很好的習慣使用上下文管理器在setup/teardown](http://stackoverflow.com/questions/8416208/in-python-is-there-a-good-idiom - 用於-使用上下文管理者合設置-拆除) – n611x007 2015-01-19 15:30:35

回答

2

setUp中更喜歡修補的主要原因是如果您有多個測試需要修補該類。在這種情況下,您需要在每個測試中複製with聲明。

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

1

有尚未使用第三種方式,作爲裝飾:

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例外情況,甚至生成包含此類情況的報告)。可能有更多的理由需要精確控制測試套件在特定時間是否(以及在何種程度上)修補「分派」。

的裝飾方法也不錯在(一)它可以讓你找出是哪個補丁去哪個測試的方式,就是函數的功能,但是沒有它承諾setUp,和(二)當給定的功能需要給定的補丁時,讀者非常清楚。

在這種情況下,上下文管理器版本似乎沒有很多優點,因爲它比裝飾器版本更難讀取。但是,如果實際上只有一種情況,或者只有很少的特定情況,那麼使用這種情況時,上下文管理器版本將會非常好。