Verwenden Sie Ihren DI-Container nicht in Ihren Komponententests. In Komponententests versuchen Sie, eine Klasse oder ein Modul isoliert zu testen, und ein DI-Container in diesem Bereich ist wenig nützlich.
Beim Integrationstest ist das anders, da Sie testen möchten, wie die Komponenten in Ihrem System zusammenarbeiten und zusammenarbeiten. In diesem Fall verwenden Sie häufig Ihre Produktions-DI-Konfiguration und tauschen einige Ihrer Dienste gegen gefälschte Dienste aus (z. B. Ihre MailService
), bleiben aber so nah wie möglich an der realen Sache.In diesem Fall verwenden Sie Ihren Container, um das gesamte Objektdiagramm aufzulösen.
Der Wunsch, einen DI-Container auch in den Komponententests zu verwenden, resultiert oft aus ineffektiven Mustern. Wenn Sie beispielsweise versuchen, die getestete Klasse mit all ihren Abhängigkeiten in jedem Test zu erstellen, erhalten Sie viel doppelten Initialisierungscode, und eine kleine Änderung in Ihrer getesteten Klasse kann in diesem Fall das System durchdringen und Sie dazu zwingen Ändern Sie Dutzende von Unit-Tests. Dies verursacht offensichtlich Wartungsprobleme.
Ein Muster, das mir in der Vergangenheit sehr geholfen hat, ist die Verwendung einer einfachen Testklassen-spezifischen Fabrikmethode. Diese Methode zentralisiert die Erstellung der zu testenden Klasse und minimiert die Anzahl der Änderungen, die durchgeführt werden müssen, wenn sich die Abhängigkeiten der getesteten Klasse ändern. Dies ist, wie eine solche Fabrik Methode aussehen könnte:
private ClassUnderTest CreateValidClassUnderTest(params object[] dependencies) {
return new ClassUnderTest(
dependencies.OfType<ILogger>().SingleOrDefault() ?? new FakeLogger(),
dependencies.OfType<IMailSender>().SingleOrDefault() ?? new FakeMailer(),
dependencies.OfType<IEventPublisher>().SingleOrDefault() ?? new FakePublisher());
}
Diese Factory-Methode enthält eine params
Array, das irgendeine Abhängigkeit akzeptiert. Der Code extrahiert die Abhängigkeiten von der Liste und falls eine bestimmte Abhängigkeit fehlt, wird eine neue falsche Implementierung eingefügt.
Dies funktioniert, da Sie in den meisten Tests nur an einer oder zwei Abhängigkeiten interessiert sind. Die anderen Abhängigkeiten sind erforderlich, damit die Klasse funktioniert, sind aber für den spezifischen Test nicht interessant. Mit der Factory-Methode können Sie also nur die Abhängigkeiten liefern, die für den Test interessant sind, während Sie das Rauschen ungenutzter Abhängigkeiten entfernen. Die Factory-Methode daher können Sie den folgenden Test schreiben:
public void Test() {
// Arrange
var logger = new ListLogger();
var cut = CreateValidClassUnderTest(logger);
// Act
cut.DoSomething();
// Arrange
Assert.IsTrue(logger.Count > 0);
}
Wenn Sie interessiert sind zu lernen, wie Lesbare Trustworthy und wartbare Tests zu schreiben, ich beraten Sie Roy Osherove Buch The Art of Unit Testing (zweite Ausgabe lesen). Das hat mir enorm geholfen.
Nicht sicher, welches Muster Sie suchen. Warum machen Sie nicht einfach Ihre Container in der Testinitialisierung (Konstruktor für xunit, z. B.)? Das Muster ist einfach - Zusammensetzung. – Artyom
Wenn Sie wirklich an Einheitentestmustern interessiert sind, sollten Sie [xUnit Test Patterns] lesen (https://www.amazon.de/xUnit-Test-Patterns-Refactoring-Code-ebook/dp/B004X1D36K/ref = dp_kinw_strp_1). – Steven