Der Grund, warum Sie Ihre Klasse nicht testen können, liegt daran, dass Ihre Klasse eine Abhängigkeit von Ihrem DI-Container übernimmt. Dies ist eine Implementierung der Service Locator anti-pattern. Es ist ein Anti-Muster, weil:
das Problem mit Service Locator ist, dass es eine Klasse Abhängigkeiten verbirgt, Laufzeitfehler statt Kompilierung-Fehler verursachen, sowie Herstellung der Code schwieriger zu warten weil es unklar wird, wann Sie eine brechende Veränderung einführen würden.
Stattdessen entwerfen Sie Ihre Klassen um
- Constructor Injection falls die Klasse ist eine Komponente (eine Klasse, die die Anwendungen Verhalten enthält), wo Sie die Abhängigkeiten zu injizieren, die eine Klasse direkt benötigt durch den Konstruktor
- Methode Injection wenn die Klasse ein datenzentrisches Objekt wie eine Entität ist, was bedeutet, dass die Abhängigkeit an die öffentliche Methode einer solchen Klasse, wo der Consumin geliefert wird Die Klasse g verwendet diese Abhängigkeit nur, speichert sie aber nicht.
Komponenten werden von Ihrem DI Container verbauten und sind in Ihrem Composition Root, während datenzentrische Objekte registriert sind new
in Code außerhalb der Zusammensetzung Root-ed up. In diesem Fall müssen Sie eine Abhängigkeit zu einem bereits konstruierten Objekt übergeben.
Falls Sie bauen und eine Komponente testen, würde der Code der Regel wie folgt aussehen:
public class ComponentA
{
private ClassName b;
public ComponentA(ClassName b)
{
this.b = b;
}
public void DoSomething()
{
// Do something with instance B
}
}
// Test class
public Class ATest
{
[test]
public void TestMethod()
{
// Arrange
B b = new FakeB();
var a = new ComponentA(b);
// Act
a.DoSomething();
// Assert
// Check whether be was invoked correctly.
}
}
Falls Sie bauen und eine Daten-zentrierte Objekt testen, die für eine seiner Operationen eine Abhängigkeit erfordert, Ihre Code würde in der Regel wie folgt aussehen:
public class EntityA
{
public string Name { get; set; }
public int Age { get; set; }
public void DoSomething(ClassName b)
{
// Do something with instance B
}
}
// Test class
public Class ATest
{
[test]
public void TestMethod()
{
// Arrange
B b = new FakeB();
var a = new EntityA { Name = "Bert", Age = 56 };
// Act
a.DoSomething(b);
// Assert
// Check whether be was invoked correctly.
}
}
so Ihre erste Frage zu beantworten:
wie d o Unit-Test eine Klasse, die IoC-Container-Klassen verwendet
Sie nicht. Ihr Anwendungscode sollte nicht von dem DI-Container abhängen, da dies zu allen Arten von Komplikationen führt, wie z. B. schwierig zu testen.
Das war eine sehr gute Erklärung! mehr davon auf SO. – Seabizkit