Ist es sinnvoll, Unit-Test-Methoden anzuwenden, bei denen die einzige Logik Wachen sind?

12

Angenommen, ich habe eine Methode wie die folgende:

public void OrderNewWidget(Widget widget)
{
   if ((widget.PartNumber > 0) && (widget.PartAvailable))
   {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

Ich habe mehrere solcher Methoden in meinem Code (die vordere Hälfte zu einem asynchronen Web-Service-Aufruf).

Ich überlege, ob es sinnvoll ist, sie mit Unit-Tests abzudecken. Ja, hier gibt es Logik, aber es ist nur Wächterlogik. (Das heißt, ich stelle sicher, dass ich das benötigte Material habe, bevor ich den Webdienstaufruf zulasse.)

Ein Teil von mir sagt, "sicher, dass Sie sie Unit-Test können, aber es ist die Zeit nicht wert" (ich bin auf einem Projekt, das bereits hinter dem Zeitplan liegt).

Aber die andere Seite von mir sagt, wenn Sie sie nicht in einer Einheit testen und jemand die Wachen wechselt, könnte es Probleme geben.

Aber der erste Teil von mir sagt zurück, wenn jemand die Wachen wechselt, dann macht man einfach mehr Arbeit für ihn (weil er jetzt die Wachen und die Unit-Tests für die Wachen ändern muss).

Wenn mein Dienst beispielsweise die Verantwortung für die Überprüfung der Widget-Verfügbarkeit übernimmt, möchte ich diesen Wächter möglicherweise nicht mehr. Wenn es im Unit Test ist, muss ich jetzt zwei Plätze wechseln.

Ich sehe Vor- und Nachteile in beide Richtungen. Also dachte ich, ich würde fragen, was andere getan haben.

Vaccano
quelle
17
Sie machen nicht "mehr Arbeit" für die Betreuer. Wenn sie die Logik ändern, müssen sie die entsprechenden Komponententests ändern. So funktioniert das. Ich sehe Ihre Nachteile nicht: Wenn Ihr Komponententest keine Änderung erfordert, würde er doch nichts testen, oder? Sie können sich genauso gut fragen, ob Unit-Tests überhaupt nützlich sind.
Andres F.
9
Dies ist kein Thema, aber ich würde die Logik ändern, um eine Ausnahme auszulösen, wenn die Teilenummer 0 oder weniger ist oder wenn das Teil nicht verfügbar ist, da es meiner Meinung nach ein Fehler wäre, jemandem zu erlauben, diese Methode mit einem aufzurufen gefälschtes Widget, das ein anderes Problem stillschweigend maskiert.
Matthew
2
@ Matthew sehr guter Punkt. Diese Funktion liegt. Die Benennung sagt dir, dass es etwas bestellen wird. Und das tut es auch nicht, aber Sie werden es nie erfahren, es sei denn, Sie wenden die gleiche Logik an, wie sie sich im Inneren befindet und die DRY ivioliert. Mit anderen Worten: Wenn das Design geändert würde, um korrekter zu sein, wäre diese Frage möglicherweise gar nicht erst gestellt worden.
28.
2
but it is not worth the time" (I am on a project that is already behind schedule).Wir sind Softwareentwickler. Das einzige Mal, wenn wir im Zeitplan sind, sind wir tot :)
maple_shaft

Antworten:

26

Ein Teil von mir sagt, "sicher, dass Sie sie Unit-Test können, aber es ist die Zeit nicht wert" (ich bin auf einem Projekt, das bereits hinter dem Zeitplan liegt).

Es sind drei sehr kurze Tests. Sie haben so viel Zeit damit verbracht, sich die Frage zu stellen.

Aber die andere Seite von mir sagt, wenn Sie sie nicht in einer Einheit testen und jemand die Wachen wechselt, könnte es Probleme geben.

Hören Sie auf diese Seite.

Aber der erste Teil von mir sagt zurück, wenn jemand die Wachen wechselt, dann macht man einfach mehr Arbeit für ihn (weil er jetzt die Wachen und die Unit-Tests für die Wachen ändern muss).

Wenn Ihr Betreuer eine TDD-Mutter ist, machen Sie es ihnen schwerer. Jede Änderung, die ich ohne eine entsprechende Änderung oder Hinzufügung von Tests vornehme, führt dazu, dass ich nachdenken muss. In der Tat würde ich wahrscheinlich die Tests hinzufügen, bevor ich fortfahre und die Änderung vornehme.

Der erste Teil von dir ist einfach falsch. Klopfen Sie den zweiten Teil auf den Rücken und denken Sie nicht mehr darüber nach.

pdr
quelle
+1 für Prägnanz, obwohl ich zu heh eine Antwort geschrieben habe
Jimmy Hoffa
3
+1. Ja, wenn sich die Anforderungen ändern, müssen einige Tests angepasst werden.
Olivier Jacot-Descombes
Während mir gefällt, was Sie sagen, habe ich in meinem Code viele Instanzen dieser Art von Aufrufen (die vordere Hälfte eines asynchronen Aufrufs). Es sind also nicht nur 3 Unit Tests. Trotzdem, wenn es der "richtige" Weg ist, dann möchte ich sie erledigen.
Vaccano
@Vaccano: Je mehr von ihnen Sie schreiben müssen, desto logischer sind die Pfade, für die Sie keine Tests haben, und desto notwendiger ist es, sie zu schreiben.
pdr
9

Es würde das Testen von Einheiten vereinfachen, wenn die Schutzlogik und die tatsächliche Reihenfolge getrennte Methoden wären.

In der WidgetKlasse

public bool IsReadyForOrdering { get { return PartNumber > 0 && PartAvailable; } }

oder eine gleichwertige Methode woanders

public bool IsWidgetReadyForOrdering(Widget widget)
{
    return widget.PartNumber > 0 && widget.PartAvailable;
}

Die Bestellmethode

public void OrderNewWidget(Widget widget)
{
   if (IsWidgetReadyForOrdering(widget)) {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

Jetzt wurde das Testen IsWidgetReadyForOrderingeinfach. Denken Sie nicht mehr lange darüber nach. Probier es aus!

Olivier Jacot-Descombes
quelle
1
Oof, stateful Logik in einer Eigenschaft .. -1, die eine Methode sein sollte, und es sollte die PartNumber, PartAvailable aufgrund seiner Einfachheit nehmen. Machen Sie es geschützt, wenn es nicht Teil der öffentlichen API sein muss, aber keine Eigenschaft. Auch ich bin im Allgemeinen anderer Meinung. Die Schutzlogik in der Methode ist völlig in Ordnung, und in meinen Augen ist es besser, weil es eine so kleine Methode ist, dass Sie die Klasse nur verschmutzen, um eine bereits kleine Methode kleiner zu machen. Fügen Sie es in diesem Fall nur dann zur Klasse hinzu, wenn es sich um eine sich wiederholende Logik handelt.
Jimmy Hoffa
1
Erstens beantwortet dies die Frage nicht. Zweitens ist es falsch. Sie müssen in beiden Fällen drei Tests schreiben. Drittens werden Implementierungsdetails unnötigerweise für den Aufruf von Code verfügbar gemacht.
pdr
8
@ JimmyHoffa: Wo sehen Sie eine zustandsbehaftete Logik in dieser Eigenschaft? Tatsächlich zeigt das Beispiel, wie die Zustandsänderungslogik (OrderNewWidget) von der Logik ohne Zustandsänderung (ReadyForOrdering) getrennt wird. Und ich bin fest davon überzeugt, dass das Extrahieren selbst dieser kleinen Funktionen den Code verbessern und nicht verschlimmern wird, wie Sie sagen. Also +1.
Doc Brown
2
Die Methode OrderNewWidgetgehört wahrscheinlich zu einer anderen Klasse als Widget, da sie ein WidgetArgument hat. Da die Methode keinen Rückgabewert hat, ist das Testen nicht offensichtlich. Sie müssten einen WigdetOrderingService-mock einfügen, der den OrderNewWidgetAsyncAnruf verfolgt.
Olivier Jacot-Descombes
2
@ JimmyHoffa: Ihre Definition von "zustandslos" bedeutet "statisch" in C #. Was Sie also sagen, ist "Eigenschaften sollten nicht auf den Status eines Objekts zugreifen". Aber auch dumme Getter greifen auf Zustandsvariablen zu, was "schreibe nur statische Eigenschaften" bedeutet - was nicht viel Sinn macht.
Doc Brown
6

Wenn Sie in Ihrem Zeitplan keine Zeit für Unit-Tests haben, aber Zeit für eine solide QA-Nutzung haben, fragen Sie, ob Sie einen Teil dieser QA-Zeit zum Schreiben von Unit-Tests verwenden oder einen Teil der QA-Zeit verbringen können Ich mache Unit-Tests oder beschäftige mich nur mit Code, der nicht Unit-getestet wurde. das System während der Laufzeit korrekt warten.

Das heißt, zu Ihrer allgemeinen Frage der Prüfung von Wachaussagen; Ja! Unbedingt Guard-Statements testen! Das sind wichtige Teile des Verhaltens dieser Methode. Sie möchten nicht herausfinden, dass jemand etwas missverstanden hat, das einen Bugfix ausführt, und Ihre Wachen entfernt oder das &&in ein " ||Würden Sie" geändert hat. Unit-Tests stellen sicher, dass a) Sie die Logik Ihrer Wachen tatsächlich richtig verstanden haben und b) niemand diese Logik später bricht, ohne eine Beschwerde zu erhalten, wenn er die Unit-Tests durchführt, in denen er erklärt, dass dies aus irgendeinem Grund so sein sollte.

Jimmy Hoffa
quelle
0

Es gibt einige ausgezeichnete Antworten, und die Punkte, die sie machen, sind sehr wichtig. Aber eines, das vermisst zu werden scheint, ist, dass Sie eine umfassende Reihe von Unit-Tests haben, die sich wie eine extrem detaillierte Spezifikation des Codes lesen. Wenn Sie die Testvalidierung weglassen, nur weil der Code so einfach ist, ist schwer einzusehen, wie es schief gehen könnte, fehlt ein Teil Ihrer Spezifikation. Wenn ich in ein Team käme, in dem diese Tests verpasst worden wären, würde ich davon ausgehen, dass Ihr Dienst seine Argumente nicht bestätigte.

Jules
quelle
-5

Code ist Code. Sie sollten versuchen, beim Testen eine 100% ige Abdeckung zu erzielen. Wenn es nicht wichtig wäre, wäre es nicht da.

SuperUser
quelle