Ich habe die Frage scherzhaft betitelt, weil ich sicher bin, dass "es darauf ankommt", aber ich habe einige spezifische Fragen.
Mein Team arbeitet mit Software, die viele tiefe Abhängigkeitsebenen aufweist, und hat sich daran gewöhnt, das Verspotten ziemlich ausführlich zu verwenden, um jedes Codemodul von den darunter liegenden Abhängigkeiten zu trennen.
Daher war ich überrascht, dass Roy Osherove in diesem Video vorgeschlagen hat, dass Sie nur etwa 5% der Zeit verspotten sollten. Ich würde vermuten, dass wir irgendwo zwischen 70-90% sitzen. Ich habe von Zeit zu Zeit auch andere ähnliche Anleitungen gesehen .
Ich sollte definieren, was ich als zwei Kategorien von "Integrationstests" betrachte, die so unterschiedlich sind, dass sie wirklich unterschiedliche Namen erhalten sollten: 1) In-Process-Tests, die mehrere Codemodule integrieren, und 2) Out-of-Process-Tests, die sprechen zu Datenbanken, Dateisystemen, Webdiensten usw. Es ist Typ 1, mit dem ich mich befasse, Tests, die mehrere Codemodule integrieren, die alle in Bearbeitung sind.
Ein Großteil der Community-Anleitungen, die ich gelesen habe, schlägt vor, dass Sie eine große Anzahl isolierter, feinkörniger Unit-Tests und eine kleine Anzahl grobkörniger End-to-End-Integrationstests bevorzugen sollten, da Unit-Tests Ihnen genaues Feedback darüber geben, wo genau Möglicherweise wurden Regressionen erstellt, aber die groben Tests, deren Einrichtung umständlich ist, überprüfen tatsächlich die End-to-End-Funktionalität des Systems.
Angesichts dessen scheint es notwendig zu sein, Spott ziemlich häufig zu verwenden, um diese separaten Codeeinheiten zu isolieren.
Gegeben ein Objektmodell wie folgt:
... Bedenken Sie auch, dass die Abhängigkeitstiefe unserer Anwendung viel tiefer geht, als ich in dieses Bild passen könnte, sodass zwischen der 2-4-Ebene und der 5-13-Ebene mehrere Ebenen N liegen.
Wenn ich eine einfache logische Entscheidung testen möchte, die in Einheit 1 getroffen wird, und wenn jede Abhängigkeit vom Konstruktor in das Codemodul injiziert wird, hängt dies davon ab, dass beispielsweise 2, 3 und 4 Konstruktor in das Modul 1 in injiziert werden Im Bild würde ich viel lieber Mocks von 2, 3 und 4 in 1 injizieren.
Andernfalls müsste ich konkrete Instanzen von 2, 3 und 4 erstellen. Dies kann schwieriger sein als nur eine zusätzliche Eingabe. Oft haben 2, 3 und 4 Konstruktoranforderungen, deren Erfüllung schwierig sein kann, und gemäß dem Diagramm (und gemäß der Realität unseres Projekts) muss ich konkrete Instanzen von N bis 13 konstruieren, um die Konstruktoren von zu erfüllen 2, 3 und 4.
Diese Situation wird schwieriger, wenn ich 2, 3 oder 4 brauche, um mich auf eine bestimmte Weise zu verhalten, damit ich die einfache logische Entscheidung in # 1 testen kann. Möglicherweise muss ich den gesamten Objektgraphen / -baum auf einmal verstehen und "mental überlegen", damit sich 2, 3 oder 4 auf die erforderliche Weise verhalten. Es scheint oft viel einfacher zu sein, myMockOfModule2.Setup (x => x.GoLeftOrRight ()) auszuführen. Returns (new Right ()); Um zu testen, dass Modul 1 wie erwartet reagiert, wenn Modul 2 es auffordert, nach rechts zu gehen.
Wenn ich konkrete Instanzen von 2 ... N ... 13 zusammen testen würde, wären die Testaufbauten sehr groß und größtenteils dupliziert. Testfehler können die Orte von Regressionsfehlern möglicherweise nicht sehr gut lokalisieren. Tests wären nicht unabhängig (ein weiterer unterstützender Link ).
Zugegeben, es ist oft sinnvoll, die unterste Schicht eher zustandsbasiert als interaktionsbasiert zu testen, da diese Module selten weitere Abhängigkeiten aufweisen. Es scheint jedoch, dass Spott per Definition fast notwendig ist, um alle Module über dem untersten zu isolieren.
Kann mir angesichts all dessen jemand sagen, was mir fehlen könnte? Überbeansprucht unser Team Spott? Oder gibt es in typischen Leitlinien für Komponententests möglicherweise die Annahme, dass die Abhängigkeitsebenen in den meisten Anwendungen so flach sind, dass es tatsächlich sinnvoll ist, alle zusammen integrierten Codemodule zu testen (was unseren Fall "besonders" macht)? Oder vielleicht anders, begrenzt unser Team unsere begrenzten Kontexte nicht angemessen?
Or is there perhaps some assumption in typical unit testing guidance that the layers of dependency in most applications will be shallow enough that it is indeed reasonable to test all of the code modules integrated together (making our case "special")?
<- Dies.