Некоторые люди утверждают, что интеграционные тесты - это все виды плохого и неправильного - все должно быть проверено модулем, что означает, что вы должны смоделировать зависимости; вариант, который по разным причинам мне не всегда нравится.
Я считаю, что в некоторых случаях юнит-тест просто ничего не доказывает.
Давайте возьмем следующую (тривиальную, наивную) реализацию репозитория (в PHP) в качестве примера:
class ProductRepository
{
private $db;
public function __construct(ConnectionInterface $db) {
$this->db = $db;
}
public function findByKeyword($keyword) {
// this might have a query builder, keyword processing, etc. - this is
// a totally naive example just to illustrate the DB dependency, mkay?
return $this->db->fetch("SELECT * FROM products p"
. " WHERE p.name LIKE :keyword", ['keyword' => $keyword]);
}
}
Допустим, я хочу доказать в тесте, что этот репозиторий действительно может найти продукты, соответствующие различным заданным ключевым словам.
Если не считать интеграционное тестирование с реальным объектом соединения, как я могу знать, что это на самом деле генерирует реальные запросы - и что эти запросы на самом деле делают то, что я думаю, они делают?
Если мне нужно смоделировать объект соединения в модульном тесте, я могу доказать только такие вещи, как «он генерирует ожидаемый запрос» - но это не значит, что он действительно будет работать … то есть, возможно, он генерирует запрос Я ожидал, но, возможно, этот запрос не делает то, что я думаю, что делает.
Другими словами, я чувствую, что тест, который делает утверждения о сгенерированном запросе, по существу не имеет значения, потому что он проверяет, как findByKeyword()
метод был реализован , но это не доказывает, что он действительно работает .
Эта проблема не ограничивается репозиториями или интеграцией баз данных - кажется, что она применима во многих случаях, когда утверждение о применении макета (test-double) только доказывает, как все реализовано, а не собирается ли оно на самом деле работа.
Как вы справляетесь с такими ситуациями?
Являются ли интеграционные тесты действительно «плохими» в таком случае?
Я понимаю, что лучше проверять одну вещь, и я также понимаю, почему интеграционное тестирование приводит к множеству путей кода, которые невозможно проверить, но в случае службы (например, хранилища), единственной целью которой является взаимодействовать с другим компонентом, как вы можете что-то протестировать без тестирования интеграции?