XUnit, AutoFixture und Moq best practice
Bin ich beim Lesen eine Menge an Dokumentation und Beispiele über, wie man richtig Einheit-test-Dinge, die die Kombination der drei Komponenten in den Titel. Ich kam mit einer test-Methode für eine Methode, auf meinem business-Logik, aber es fühlt sich sehr klobig und schmutzig.
Ich würde gerne einige Rückmeldungen von Menschen, die mehr Erfahrung auf diesem Thema, um zu sehen, wie kann ich es verbessern.
Hier ist der code, Erklärung folgt:
[Fact]
public void ShouldGetItemWithSameId()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var facade = fixture.Freeze<Mock<IDataFacade>>();
facade.Setup(c => c.Get(It.IsAny<int>())).Returns((int i) => new Item { Key = i });
var sut = fixture.Create<BusinessLogic>();
var expected = fixture.Create<int>();
Assert.Equal(expected, sut.Get(expected).Key);
}
Meine BusinessLogic
- Klasse nimmt ein IDataFacade
als Konstruktor-parameter, die verantwortlich in seiner Get(int)
Methode auf, um das Element mit der gleichen Id, ziemlich grundlegende Dinge.
Habe ich eingefroren, die IDataFacade
mock und ich es bis zu dem erstellen einer object-matching-Id in It.IsAny<int>
. Ich habe dann meine SUT und testen Sie es. Funktioniert einwandfrei.
Ich würde gerne verstehen, ob ich das verbessern kann, Dinge, die unter Berücksichtigung der folgenden:
- Ich habe zum test komplexer Methoden, wie ein
Query
Methode, die eine Klasse enthält eine Menge von Eigenschaften, die verwendet werden, die als Filter auf passende Eigenschaften auf den Typ abgefragt werden. In diesem Fall würde ich nicht wissen, wie man richtig führen Sie die "Setup" - Teil des Prototyps, da habe ich zu initialisieren, alle oder fast alle, der Eigenschaften der zurückgegebenen Typ, und in diesem Szenario ist es nicht ein einzelnes Element, sondern eine ganze Sammlung - Der setup-Teil fühlt sich fehl am Platz, ich möchte in der Lage sein zu verwenden es in mehr Methoden
Habe ich einige andere tests mit Theory
mit AutoMoqData
aber ich war nicht in der Lage, dies zu erreichen test (und ich denke, die komplexer sind) diesen Ansatz verwenden, also habe ich wieder umgestellt auf nur Fact
mit manuell instanziiert Leuchte.
Jede Hilfe wird sehr geschätzt.
- Haben Sie als (Auto -) NSubstitute - ich hielt meinen 'was ist falsch mit Moq' defult Einstellung zu lange. weareadaptive.com/blog/2014/09/30/why-nsubstitute
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dein test sieht gut aus für mich, obwohl ich empfehlen würde, eine änderung zu. Die folgende Zeile könnte angezogen werden, bis der erwartete Wert zurück, wenn der erwartete Wert übergeben wird:
Alles, was Sie würde tun müssen, bewegen sich die erwarteten Variablen, und ändern Sie die Ist.IsAny etwa so:
Ich glaube nicht, dass Sie benötigen würde, um durch die Initialisierung alle Werte auf den zurückgegebenen Typ. Ich vermute, Ihr DataFacade gibt ein Objekt (oder eine Liste von in diesem Fall)? Alles, was Sie würde tun müssen ist, stellen Sie sicher, dass die zurückgegebenen Objekte passen die Verweise an diejenigen zurückgegeben, die von der DataFacade, brauchen Sie nicht zu befürchten, Eigenschaften etc, da bist du nicht die Prüfung der Bau dieser Objekte, so dass Sie zurückgegeben. Wenn ich falsch verstanden habe, und Sie den Bau der Objekte in der BusinessLogic dann ist das eine andere Sache. Ich persönlich hätte nicht die business-Logik abhängig von der Daten-Schicht, aber das ist eine andere Diskussion. 🙂
Können Sie. Entweder extrahieren Sie Sie auf eine eigene Methode oder, sofern es anwendbar ist, zu jedem test in der Klasse, setzen es in einer setup-Methode. Ich bin nicht vertraut mit XUnit aber alle anderen test-Frameworks, die ich verwendet habe, stellt die Möglichkeit bereit, gemeinsam eingerichtet, so dass ich bezweifle, XUnit anders sein wird.
Und mein letzter Kommentar, behandeln Sie Ihre test-code, wie würden Sie behandeln Ihre Produktion code, wenn es sieht ein Durcheinander Dinge tun, um es besser zu machen. Tests sind ideal für die Beschreibung des Verhaltens eines Systems, aber wenn Sie sind schwer zu Lesen (und zu pflegen) Sie verlieren eine Menge Wert.
Bearbeiten, stellt sich heraus, dass ist nicht mein letzter Kommentar! Wenn Sie neu zu TDD, die ich bin nicht sicher, dass Sie sind, fallen nicht in die Falle, jede Prüfung und jede Klasse in Ihrer Anwendung, es ist ein gemeinsames Muster, das hat sich verbreitet und es entwertet TDD meiner Meinung nach. Ich habe geschrieben ein blog-post auf meine Gefühle und Ian Cooper hat eine hervorragende Präsentation auf die Sache.
var expected = fixture.Create<int>();
wirdvar expected = Any.Integer();
Insgesamt, die original-test sieht gut aus. Es ist nicht möglich und auch nicht leicht zu extrahieren, die Einrichtung von Stubs und Mocks aus dem test in einer generischen Weise.
Was Sie kann aber tun, ist, minimieren Sie die Arrange-phase der test. Hier der original-test-re-geschrieben, mit AutoFixture.Xunit's eigene unit-Test-DSL:
Den
TestConventions
Attribut ist definiert als:HTH
Sample-Typen verwendet, im Beispiel:
Einige Grundlagen:
Ihre Test-Klasse instanziiert wird (und den zugehörigen Konstruktor genannt), die vor jedem einzelnen Test ausgeführt. wenn z.B. Ihre Test-Klasse hat drei Methoden mit [der Tat] - Attribut, es wird instanziiert drei mal
Einer TestFixture-Klasse ist eine weitere Klasse, die gemeint ist, instanziert ein einziges mal für alle Tests in der test-Klasse.
Diese Arbeit zu machen, Ihre test-Klasse implementieren muss, die IUseFixture-Schnittstelle, implementieren, z.B. ein Mitglied SetFixture()
Verwenden, können Sie den gleichen MyTestFixture Klasse für mehrere Test-Klassen.
Innerhalb der TestFixture Sie tun all die Mock-Setups.
Hier das Allgemeine layout: