2014-06-16 48 views
2

後比方說,我有這樣的幾個測試:銷燬Python中的模擬測試

class TestMyTest(unittest.TestCase): 

    def SetUpClass(cls): 
     cls.my_lib = MyLib() 

    def my_first_test(self): 
     self.my_lib.my_function = Mock(return_value=True) 
     self.assertTrue(self.my_lib.run_my_function(), 'my function failed') 

    def my_second_test(self): 
     # Some other test that calls self.my_lib.my_function... 

而讓我們說我有MyLib中是這樣的:

class MyLib(Object): 

    def my_function(self): 
     # This function does a whole bunch of stuff using an external API 
     # ... 

    def run_my_function(self): 
     result = self.my_function() 
     # Does some more stuff 
     # ... 

在my_first_test我我嘲笑my_lib.my_function,並在函數執行時返回True。在這個例子中,我的斷言是調用run_my_function(),它是來自同一個庫的另一個函數,除此之外,它調用my_lib.my_function。但是,當執行my_second_test時,我不想調用模擬函數,而是調用真正的函數。所以我想我需要在運行my_first_test之後以某種方式銷燬模擬,也許在tearDown()過程中。我如何摧毀這個模擬?

我編輯了我的原始問題以添加更多細節,因爲看起來並不那麼清楚,對此抱歉。

+2

你的對象是在自己上運行測試並嘲笑它自己的實現嗎?這是在惹麻煩。通常你有一個測試類(使用內建的'unittest'),它與被測試的類不同。編輯 - 這將爲每個測試創建一個新的對象實例,所以不需要重置狀態。 – Joe

+0

我使用了'self.assertTrue'來表明這是'unittest.TestCase'裏的所有內容,但是爲了簡單起見,它被省略了。如果情況並非如此,有些事情是非常錯誤的。 –

+1

@PatrickCollins但是'self.my_lib.my_function'呢?這看起來像是測試對象的實現,或者他在設置中保留一個對象。也許你是對的,這是後者。 – Joe

回答

2

你可以這樣做:

class TestYourLib(unittest.TestCase): 

    def setUp(self): 
     self.my_lib = MyLib() 

    def test_my_first_test(self): 
     self.my_lib.my_function = Mock(return_value=True) 
     self.assertTrue(self.run_my_function(), 'my function failed') 

    def test_my_second_test(self): 
     # Some other test that calls self.my_lib.my_function... 

然後Mock被傳遞出的範圍時setUp被稱爲下一個測試案例「破壞」。

+1

你有些事情非常困惑。 'run_my_function'沒有被模擬,它是被測試的方法。嘲笑正在測試的東西使0.00%有意義。這是'my_lib ...'被嘲笑,因爲'run_my_function'正在使用它,我們也不想測試'mylib'。這是一個完全標準的用例,唯一不會混淆'my_lib'的方法就是依賴注入*所有被忽視的東西,而這並不實際。 – delnan

+0

@delnan我認爲你需要改變'my_lib'的某個屬性來獲得'run_my_function'的方式 - 在實例化之後,我認爲它就像依賴注入一樣。我希望將'MyLib(the_object = Mock(...))'或'self.my_lib.run_my_function(the_object = Mock(...))'看作是合理的,鬆散耦合的實現。 'self.my_lib.my_function = Mock(return_value = True)'清楚地表明這是'run_my_function'內部被模擬的內容,否則'my_lib.my_function'和'mylib.run_my_function'名稱會非常混亂。 –

+1

我不認爲這個測試是非常有意義的,但它似乎是@Cas所要求的。 –

1

破壞模擬不會這樣做。您必須重新分配self.my_lib.my_function或以不同的方式撥打Mock(return_value=True)

首先是帕特里克似乎提出的建議。