Прежде чем беспокоиться о тестировании 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()
.