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 或 stub 以消除访问数据库的需要。

如果有使用 Mocks 和 Stubs 经验的人给我一些关于在我的案例中使用 mocks 和 stubs 的提示,我将非常感激。

4

1 回答 1

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()为更小、定义更严格(因此更可测试)的部分。

Taking the same logic a step up in the hierarchy, you might create a MockFoo class that would know how to respond in simplified ways to method_one() and method_two().

于 2011-06-03T23:47:22.173 回答