2016-07-28 10 views
1

Was ist die beste Vorgehensweise zum Verifizieren eines Methodenaufrufs mit komplexen Parametern beim Komponententest?Best Practice für die Überprüfung von Einheitentestmethodenparametern

sagen, ich bin eine Funktion wie diese Prüfung:

class ClassA { 
    ClassB dependency; 

    void someFunction(SomeInputForA input) { 
    // do some thing 
    dependency.anotherFunction(differentInput); 
    } 
} 

Die beiden Optionen, die ich für die Überprüfung denken kann, dass someFunction Anrufe anotherFunction mit dem richtigen Eingang sind:

A) kann einen Verifizierungs auf der mock der Abhängigkeit für anotherFunction

unitUnderTest.dependency = mockClassB; 

InputClass expectedDifferentInput = ... ; 

verify(mockClassB).anotherFunction(expectedDifferentInput); 

B) tun ein Argument Fänger auf den Anruf von anotherFunction und behaupten t Aufruf er Eigenschaften

Gibt es hier einen vorgeschlagenen Pfad? Ich würde mich der Captur-Methode anlehnen, weil sie sich strenger anfühlt und nicht auf Objekte angewiesen ist, wenn die Implementierung korrekt ist.

Gedanken?

+0

Ich würde die Werte erfassen und bestätigen, wenn sie von der Methode erstellt oder verwaltet werden. Wenn sie durchgereicht werden, d. H. Als eine Dienstleistung, dann ist A geeignet. – Compass

Antwort

1

Ist differenceinput computed off input? Wenn das der Fall ist, dann ist Ihr B) der bessere Weg zu gehen, wie Sie für Eingang A sagen. Sie erwarten, dass ClassA dies in expectedDifferentInput ändert und überprüfen möchte, dass die delegierende Klasse (ClassB) aufgerufen wird. Sie überprüfen die Transformation der Eingabe- und Delegierungslogik von ClassA.

Wenn differentInput keine Beziehung zur Eingabe hat, müssen Sie den Captor nicht verwenden, da Sie nur die Delegierung überprüfen.

Jeder öffentliche Aufrufer an someFunction auf ClassA sollte nicht über ClassB wissen müssen, so kann gesagt werden, beide Methoden A) und B) sind tatsächlich white box testing, in diesem Fall und so könnten Sie die Entführer sowieso verwenden. Wenn Sie die Eingabe für someFunction ändern, können die Entscheider Ihnen auch dabei helfen, Randfälle zu erkennen, wenn differenceInput aus der Eingabe berechnet wird.

0

Sie können immer Matcher für das Objekt verwenden, das an mockClassB.anotherFunction() übergeben wurde. Zum Beispiel, wenn Sie Felder auf einem Objekt vergleichen wollen, können Sie schreiben:

Matcher<YourClass> yourMatcher = Matchers.hasProperty("yourProperty", Matchers.equals(whatever)); 
verify(mockClassB).anotherFunction(argThat(yourMatcher)); 

ziehe ich es auf diese Weise, da Sie Syntax für die gemeinsam nutzen können, wann und das überprüfen für die Matcher und Sie eine beliebige Kombination von kombinieren Matcher. Sie müssen nur die neuesten Mockito- und Hamcrest-Bibliotheken einbinden, damit dies funktioniert.

0

Ich habe argument captors aber sehr sparsam verwendet. Das größte Problem, auf das Sie stoßen, ist, dass diese Route fragile Komponententests erstellt. Und niemand ist glücklich, wenn sie einen kleinen Wechsel zu einer Klasse machen und dann mit Komponententests in Rufklassen kämpfen, die nicht betroffen sein sollten.

Das gesagt, absolut müssen Sie schließlich sicherstellen, dass richtige Anrufe getätigt werden. Aber wenn Sie sich darauf verlassen, dass eine Equals-Überschreibung funktioniert, dann verlassen Sie sich darauf, dass diese Klasse eine equals-Methode hat, die funktioniert, und das ist dann Teil des Vertrags dieser Klasse (und der in dieser Klasse getesteten Einheit), was vernünftig ist.

Deshalb würde ich dafür stimmen, es einfach zu halten und einfach nur zu überprüfen. Das Gleiche gilt am Ende, aber dein Komponententest ist weniger anfällig.

Verwandte Themen