ich mit großer Teil der obigen einverstanden sind, in Zusammenhang mit Unit-Tests. Ich denke jedoch, dass es wichtig ist, darauf hinzuweisen, dass die Verwendung von Mock-Repositories und Komponententests nicht die gleiche Teststufe bietet wie ein DB-Integrationstest.
Zum Beispiel haben unsere Datenbanken häufig kaskadierende Löschungen, die direkt in das Schema eingebaut sind. In diesem Fall werden beim Löschen einer primären Entität in einem Aggregat automatisch alle untergeordneten Entitäten gelöscht. Dies gilt jedoch nicht automatisch für ein verspottetes Repository, das nicht von einer physischen Datenbank mit diesen Geschäftsregeln gesichert wurde (es sei denn, Sie haben alle diese Regeln im Mock erstellt). Das ist wichtig, denn wenn jemand vorbeikommt und das Design meines Schemas ändert, brauche ich es, um meine Tests zu unterbrechen, damit ich den Code/das Schema entsprechend anpassen kann. Ich weiß zu schätzen, dass dies Integrationstests und keine Unit-Tests sind, aber ich denke, es war erwähnenswert.
Meine bevorzugte Option besteht darin, eine Master-Design-Datenbank zu erstellen, die Beispieldaten enthält (die gleiche Art von Daten, die Sie in Ihren Mocks erstellen würden). Zu Beginn jedes Testlaufs habe ich ein automatisiertes Skript, das eine Sicherung der MasterDB erstellt und diese in "TestDB" wiederherstellt (was alle meine Tests verwenden). Auf diese Weise verwalte ich ein Repository sauberer Testdaten im Master, das sich bei jedem Testlauf neu erstellt. Meine Tests können mit den Daten experimentieren und alle benötigten Szenarien testen.
Wenn ich die Anwendung debuggen, habe ich ein anderes Skript, das sichert und die Master-DB zu einer DEV-Datenbank wiederherstellt. Ich kann auch hier mit Daten herumspielen, ohne mich um den Verlust meiner Beispieldaten sorgen zu müssen. Normalerweise führe ich dieses bestimmte Skript nicht in jeder Sitzung aus, da die Verzögerung darauf wartet, dass die Datenbank neu erstellt wird. Ich kann es einmal am Tag laufen und dann die App den ganzen Tag über ausprobieren. Wenn ich zum Beispiel alle Datensätze aus einer Tabelle als Teil meines Debugging lösche, würde ich das Skript ausführen, um die DevDB neu zu erstellen, wenn ich fertig bin.
Diese Schritte klingen, als würden sie dem Prozess eine riesige Menge an Zeit hinzufügen, aber tatsächlich - sie tun es nicht. Unsere Anwendung hat derzeit etwa 3500 Tests, von denen etwa 3000 irgendwann auf die DB zugreifen. Die Sicherung und Wiederherstellung der Datenbank dauert normalerweise etwa 10-12 Sekunden zu Beginn jedes Testlaufs. Und da die ganze Testsuite erst nach dem Einchecken von TFS ausgeführt wird, macht es uns nichts aus, wenn wir noch eine Weile warten müssen. An einem durchschnittlichen Tag dauert unsere gesamte Testsuite ungefähr 15-20 Minuten.
Ich schätze und akzeptiere, dass Integrationstests viel langsamer als Komponententests sind (wegen der inhärenten Notwendigkeit, eine echte DB zu verwenden), aber es stellt eher die "echte Welt" -App dar. Zum Beispiel, Mock-Repositorys geben keine DB-Fehlercodes zurück, keine Zeitüberschreitung, sie sperren nicht, sie haben nicht genug Speicherplatz, usw.
Komponententests sind in Ordnung für einfache Berechnungen, grundlegende Geschäftsregeln usw. und sicherlich sind sie absolut die beste Wahl für die meisten Operationen, die keinen Zugriff auf DB (oder andere Ressourcen) beinhalten. Aber ich glaube nicht, dass sie so wertvoll sind wie Integrationstests - die Leute reden viel über Komponententests, aber über Integrationstests wird wenig gesagt.
Ich erwarte, dass diejenigen, die sich leidenschaftlich für Komponententests begeistern, mir dafür Flammen schicken werden. Das ist in Ordnung - ich versuche nur, etwas Gleichgewicht zu schaffen und die Leute daran zu erinnern, dass Projekte, die voll von bestandenen Komponententests sind, immer noch in dem Moment scheitern können, in dem Sie sie im Feld implementieren.
Ich benutze den gleichen DataContext Mocking-Code und es funktioniert gut –