Mit toString() für Unit-Tests in Java
Wenn in Ihrem Gerät zu testen, Ihre Absicht, dass alle Felder des Objekts zu behaupten ist sind Gleichen, die toString()
Methode des Objekts zu prüfenden Geräten sind Es wurde also eine Zeichenfolge zurückgegeben, die Schlüsselwerte für alle Felder anzeigt.
Aber wie Sie unterstrichen haben, in der Zeit können die Felder der Klasse ändern und so Ihre toString()
Methode möglicherweise nicht tatsächliche Felder widerspiegeln und die toString()
Methode war kein Design dafür.
Der Test hängt von toString() ab, das im Dokument nicht formell definiert ist und daher in jeder zukünftigen Version geändert werden kann.
Es gibt Alternativen zu toString()
, die ohne
schönen Code zu schreiben erlaubt beschränke Sie eine toString()
Methode mit allen Schlüssel-Wert-Feldern zurückgegeben oder Misch toString()
ursprüngliche Absicht für das Debuggen Zweck mit Behauptung Zwecke zu halten.
Außerdem sollten Komponententests das Verhalten der getesteten Methode dokumentieren.
A-Code als die folgenden ist nicht selbsterklärend auf dem erwarteten Verhalten:
assertEquals(someExpression.toString() ,"[a, b, c]");
1) Reflection Bibliothek
Die Idee Java Reflexion Mechanismen mit JUnit Behauptung Mechanismen (oder jede Testeinheit mischt API, die Sie verwenden).
Mit der Reflexion können Sie vergleichen, ob jedes Feld von zwei Objekten des gleichen Typs gleich ist. Die Idee ist folgende: Sie erstellen eine Fehlermeldung, die Felder anzeigt, in denen die Gleichheit zwischen zwei Feldern nicht respektiert wird und aus welchen Gründen.
Wenn alle Felder durch Reflektion verglichen wurden, verwenden Sie den Unit Test-Mechanismus, wenn die Fehlermeldung nicht null ist, um eine Fehlerausnahme mit einer relevanten Fehlermeldung zu erzeugen, die Sie zuvor erstellt haben.
Ansonsten ist die Behauptung ein Erfolg. Ich benutze es regelmäßig bei meinem Projekt, wenn es relevant wird.
Sie können es selbst tun, oder Sie können API wie Untils verwenden, die die Arbeit für Sie erledigen können.
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
ReflectionAssert.assertReflectionEquals(user1, user2);
Persönlich habe ich meine eigene Bibliothek den Job mit der Möglichkeit zu tun, mehrere Anpassungen in der Behauptung hinzuzufügen. Es ist nicht sehr schwer zu tun und Sie können von Untils inspirieren.
2) Unit-Test-Matcher Bibliothek
Ich denke, dass es eine bessere Alternative ist.
Sie könnten Harmcrest oder AssertJ verwenden.
Es ist ausführlicher, dass reine Reflexion, sondern es hat auch große Vorteile:
- es durch die bewährte Methode erwartet speziell das Verhalten dokumentiert.
- es fließend Methoden bietet behaupten
- es mehrere Behauptung Funktionen bietet Kesselblech Code zu reduzieren in Einheit
Mit AssertJ testet, können Sie diesen Code ersetzen könnte:
assertEquals(foo.toString() ,"[value1=a, value1=b, value1=c]");
wo foo eine Foo-Instanz einer Klasse definiert als:
public class Foo{
private String value1;
private String value2;
private String value3;
// getters
}
von etwas wie :
Assertions.assertThat(someExpression)
.extracting(Foo::getValue1, Foo::getValue2, Foo::getValue3)
.containsExactly(a, b, c);
Es ist eine gute Idee, toString zu testen, wenn 'toString' Teil der API des CUT ist. Sonst ist es eine schlechte Idee. –
@BoristheSpider Es ist nicht Teil der getesteten API. Ist es eine schlechte Idee toString() zu verwenden, weil es sich in der Zukunft ändern kann? – Ofer
Wenn sich Ihr 'toString()' in Zukunft ändert, müssen Sie auch Ihren Test ändern. Und das ist ein weiterer Vorteil von Komponententests. Offensichtlich ist der Vergleich einer Liste mit ihrem toString fehlerhaft –