2011-06-03 56 views
4

我有一個方法,它調用其他兩個方法。嘲笑或存根?

def main_method(self, query): 
    result = self.method_one(query) 
    count = self.method_two(result) 
    return count 

def method_one(self, query): 
    #Do some stuff based on results. 
    #This method hits the database. 
    return result 

def method_two(self, result): 
    #Do some stuff based on result. 
    #This method also hits the database. 
    return count 

我對單元測試不是很有經驗,也從來沒有與Mocks和Stubs合作過。

我不太確定如何爲我的第一種方法創建單元測試。由於method_one和method_two多次訪問數據庫並且它們非常昂貴,因此我決定使用mox創建一個模擬或存根,以消除打擊數據庫的需要。

我真的很感激,如果有經驗的人使用Mock和Stubs給我一些關於使用mock和stubs的案例。

謝謝先進。

回答

5

在擔心測試main_method()之前,先測試更小的方法。考慮method_one()。爲了討論的目的,讓我們假設它存在於這樣一個類:

class Foo(object): 
    def method_one(self, query): 
     # Big nasty query that hits the database really hard!! 
     return query.all() 

爲了測試方法而無需訪問數據庫,我們需要知道如何向all()方法響應的對象。例如:

class MockQuery(object): 
    def all(self): 
     return [1,2] 

現在我們可以測試一下:

f = Foo() 
q = MockQuery() 
assert f.method_one(q) == [1,2] 

這是一個基本的例證。現實世界通常更加複雜。爲了值得寫測試的麻煩,你的模擬all()可能會做一些比返回常量更有趣的事情。沿着類似的路線,如果method_one()包含一堆其他邏輯,我們的MockQuery可能需要更加詳細 - 也就是說,能夠適當地響應更多的方法。通常,在嘗試測試代碼時,您會意識到您的原始設計已經負擔過重:您可能需要將method_one()重構爲更小,更嚴格定義的 - 因此更易測試的部分。

在層次結構中採用相同的邏輯,您可以創建MockFoo類,該類可以知道如何以簡化方式響應method_one()method_two()