2017-07-20 32 views
0

我已經搜索了幾個小時。甚至找不到任何人試圖做到這一點。嗯。如何在python單元測試中覆蓋(不補丁)單一方法

我相信我必須重寫類實例中的單個方法。我做不是的意思是patch(return_value=)。我需要讓有問題的方法做一些涉及self的事情。

我會盡量分解它。寬鬆意譯和包括的很多東西我試過了,這是不行的一個...

class SetupClass(object): 
    def set_some_stuff(self): 
     data_list = functon_cannot_be_run_on_test_platform() 
     self.something = data_list[0] 
     self.something_else = data_list[1] 

class UUT(object): 
    self.config = SetupClass() 
    assert self.config.something == 'foo' 

class UnitTests(TestCase): 

    @patch('SetupClass') 
    def test_UUT(self, mock1): 

     def WedgeClass(SetupClass): 
      def set_some_stuff(self): 
       self.something = 'foo' 
       pass # I'm a Python newbie, in too deep 

     wedge_class = WedgeClass() 
     mock1.return_value = wedge_class # doesn't work. context errors 

     uut = UUT() # <-- would crash here, because assert above 

假設我不能更改UUTSetupClass

由於SetupClass.functon_cannot_be_run_on_test_platform()的原因,斷言將失敗,因此測試甚至無法啓動。 請注意,只是嘲諷SetupClass.functon_cannot_be_run_on_test_platform不會解決問題,因爲原因。

自動取款機,我想唯一的方法來解決這個混亂是以某種方式覆蓋SetupClass.set_some_stuff。我不能簡單地嘲笑整個班級,因爲UUT也嚴重依賴其他功能。我需要一切工作,除了這一個方法我需要該方法能夠訪問,self在原來的意圖相同的上下文中。

我嘗試了各種涉及子類和mock.return_value等事情,我寧願不記得造成的痛苦。 :p

我的王國爲測試驅動的代碼在第一位!這段代碼包含了一個co-dependencies的卷積。 : -/

從示例代碼我寫了我的頭在咖啡館的頂部的多個錯誤
+0

'class'必須用'類UUT'開始,不是'高清UUT'和Ident是關閉 – Gang

+0

@Gang ...哦,是的。只是錯別字。我已經編輯了十幾次僞代碼。抱歉。目前的版本更接近我實際嘗試的版本。 – gruvin

+0

'def WedgeClass'應該在'class UnitTests'之外?函數'__init __()'或其他函數中的'class UUT'中有2行? – Gang

回答

1

除了...

的問題(大部分),我用return_value代替side_effect到用我自己的子類「替換」修補後的類。

我的需要現在可能更清楚地說明,就是在被測單元(UUT)的一個類中重寫一個單獨的方法set_some_stuff,但不要嘲笑這個類。

該方法發出幾個'self.foo = bar'語句,我想爲測試目的而更改該語句。因此,嘲笑方法的(未使用的)返回值是不夠的......而patch.object似乎失去了類的上下文,「自身未知」或類似的東西。

最後,這裏是工作的代碼,做什麼,我需要......

import unittest 
import mock 

class SetupClass(object): 
    def set_some_stuff(self): 
     data_list = ['data not available', 'on test_platform'] # CRASH! 
     self.something = data_list[0] 
     self.something_else = data_list[1] 

class UUT: 
    def __init__(self): 
     self.config = SetupClass() 
     self.config.set_some_stuff() 
     assert self.config.something == 'foo' # <-- used to crash before here ... 
     self.got_here = True # ... but now the override method from 
          # WedgeClass is being used! :=) 

""" 
Subclass the original class, overriding just the method in question. Then set 
the subclass as the side_effect of the patched original, effectively replacing it. 
""" 
class WedgeClass(SetupClass): 
    def set_some_stuff(self): 
     self.something = 'foo' 
     pass # I'm a Python newbie, in too deep 

class UnitTests(unittest.TestCase): 

    @mock.patch(__module__+'.SetupClass') 
    def test_UUT(self, mock1): 
     wedge_class = WedgeClass() 
     mock1.side_effect = WedgeClass # <--- Ureka! 'side_effect' not 'return_value' was the ley! 

     uut = UUT() 
     self.assertTrue(uut.got_here)