2012-11-07 41 views
0

我有一組共享一些基本檢查的操作。我的代碼如下所示:單元測試方法包裝器

def is_valid(param): …some pretty complex things unit-tested on their own… 

class BaseAction(object): 
    def run(self, param): 
     if not is_valid(param): 
      raise ValueError(…) 

     return self.do_run(param) 

class Jump(BaseAction): 
    def do_run(self, param): … 

class Sing(BaseAction): 
    def do_run(self, param): … 

我該如何對BaseAction.run執行驗證這一事實進行單元測試?

我想我可以對Jump.run和Sing.run進行單元測試,但是爲了正確地做到這一點,我需要爲BaseAction的每個子類編寫測試,這可能是很多情況。這也意味着將子類的測試與基類的方法進行測試。

回答

2

你會單元測試is_valid()函數本身。然後,您只需要測試的事實,.run()引起了ValueError異常過去了無效輸入:

with self.assertRaises(ValueError): 
    objectundertest.run(invalid_parameter) 

既然你已經有了一個單元測試爲is_valid()本身,你的單元測試代碼爲.run()並不需要把重點放在它的功能。您可以專注於.run()的獨特功能。

就你的情況而言BaseAction是爲子類提供服務的單元;我測試這是一個模擬的子類:

class MockAction(BaseAction): 
    run_called = None 

    def do_run(self, param): 
     self.run_called = param 

,所以你可以檢查是否確實rundo_run與預期param值。

+0

我應該爲'objectundertest'做些什麼? BaseAction()(可能是一種抽象類)?一個子類? – liori

+0

@ liori:我擴大了一點;子類'BaseAction()'僅用於單元測試。這可以讓你專注於基類單元的孤立。 –

1

如果你想保持你的基類的邏輯,請參閱Martijn Pieters的答案。

但是,一種可能性是重構代碼以使驗證發生在不屬於Base類的函數/類中。也許實際運行本身可以檢查這些動作類...

class Jump(object): 
    def run(self, param): 
     ... 

def run_action(action, param): 
    if not is_valid(param): 
     raise ValueError(…) 

    return action.run(param) 

單元測試的行爲更容易(你不需要擔心基本邏輯),也不會打破所有的「跳轉」單元測試如果「BaseAction」以某種方式中斷。 「run_action」(如果你願意的話,你可以創建一個類而不是函數)本身可以很容易地測試(你可以創建一個假的「Action」對象)。

+0

是的,這個表述使得它更加明確。謝謝。 – liori