一部の人々は、統合テストはすべての種類の悪い点と間違っていると主張しています -すべてを単体テストする必要があります。さまざまな理由で、私は常に好きではないオプション。
場合によっては、単体テストでは何も証明されないことがわかります。
例として、次の(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)の使用についてアサーションを行うと物事の実装方法が証明されるだけで、実際に動作します。
このような状況にどのように対処しますか?
このような場合、統合テストは本当に「悪い」のですか?
私は1つのことをテストする方が良いという点を理解し、統合テストが無数のコードパスにつながる理由を理解しますが、そのすべてをテストすることはできません-しかし、唯一の目的があるサービス(リポジトリなど)の場合別のコンポーネントと対話するために、統合テストなしで実際に何かをテストするにはどうすればよいですか?