Einige Leute behaupten, dass Integrationstests alle Arten von schlecht und falsch sind - alles muss Unit-getestet sein, was bedeutet, dass man Abhängigkeiten verspotten muss; Eine Option, die ich aus verschiedenen Gründen nicht immer mag.
Ich finde, dass ein Unit-Test in einigen Fällen einfach nichts beweist.
Nehmen wir als Beispiel die folgende (triviale, naive) Repository-Implementierung (in 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]);
}
}
Angenommen, ich möchte in einem Test nachweisen, dass dieses Repository tatsächlich Produkte finden kann, die mit verschiedenen angegebenen Schlüsselwörtern übereinstimmen.
Wie kann ich nach einem Integrationstest mit einem realen Verbindungsobjekt feststellen, dass tatsächlich echte Abfragen generiert werden - und dass diese Abfragen tatsächlich das tun, was ich denke, dass sie tun?
Wenn ich das Verbindungsobjekt in einem Unit-Test verspotten muss, kann ich nur beweisen, dass "es die erwartete Abfrage generiert" - aber das bedeutet nicht, dass es tatsächlich funktionieren wird ... das heißt, dass es möglicherweise die Abfrage generiert Ich habe es erwartet, aber vielleicht macht diese Abfrage nicht das, was ich denke.
Mit anderen Worten, ich fühle mich wie ein Test, der Aussagen über die generierte Abfrage macht, im Wesentlichen wertlos ist, weil er testet, wie die findByKeyword()
Methode implementiert wurde , aber das beweist nicht, dass sie tatsächlich funktioniert .
Dieses Problem ist nicht auf Repositorys oder die Datenbankintegration beschränkt - es scheint in vielen Fällen zutreffend zu sein, in denen Aussagen über die Verwendung eines Mocks (Test-Double) nur beweisen, wie die Dinge implementiert sind, nicht, ob sie implementiert werden eigentlich arbeiten.
Wie gehen Sie mit solchen Situationen um?
Sind Integrationstests in einem solchen Fall wirklich "schlecht"?
Ich verstehe, dass es besser ist, eine Sache zu testen, und ich verstehe auch, warum Integrationstests zu unzähligen Codepfaden führen, die alle nicht getestet werden können - aber im Fall eines Dienstes (wie z. B. eines Repositorys), dessen einziger Zweck darin besteht Wie können Sie ohne Integrationstests wirklich etwas testen, um mit einer anderen Komponente zu interagieren?