2011-06-03 80 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()