449 Stimmen

Warum bietet JUnit keine assertNotEquals-Methoden?

Weiß jemand, warum JUnit 4 bietet assertEquals(foo,bar) aber nicht assertNotEqual(foo,bar) Methoden?

Sie bietet assertNotSame (entspricht assertSame ) und assertFalse (entspricht assertTrue ), so dass es seltsam erscheint, dass sie sich nicht die Mühe gemacht haben, auch assertNotEqual .

Übrigens, ich weiß, dass JUnit-addons die Methoden, die ich suche, bereitstellt. Ich frage nur aus Neugierde.

6voto

Akshay Vijay Jain Punkte 8985

Ich arbeite an JUnit in Java 8 Umgebung, mit jUnit4.12

für mich: der Compiler war nicht in der Lage, die Methode assertNotEquals zu finden, selbst wenn ich
import org.junit.Assert;

Also änderte ich
assertNotEquals("addb", string);
zu
Assert.assertNotEquals("addb", string);

Wenn Sie also ein Problem haben mit assertNotEqual nicht erkannt, dann ändern Sie es in Assert.assertNotEquals(,); das sollte Ihr Problem lösen

3voto

Mark Levison Punkte 774

Der offensichtliche Grund, warum die Leute assertNotEquals() wollten, war, Builtins zu vergleichen, ohne sie zuerst in vollwertige Objekte umwandeln zu müssen:

Ausführliches Beispiel:

....
assertThat(1, not(equalTo(Integer.valueOf(winningBidderId))));
....

vs.

assertNotEqual(1, winningBidderId);

Da Eclipse standardmäßig kein JUnit 4.11 enthält, müssen Sie leider sehr ausführlich sein.

Caveat Ich glaube nicht, dass die '1' muss in einem Integer.valueOf() gewickelt werden, aber da ich neu von .NET zurückgegeben werden, zählen Sie nicht auf meine Korrektheit.

2voto

Chris Kelly Punkte 37

Es ist besser, Hamcrest für negative Assertions zu verwenden, als assertFalse, da der Testbericht im ersteren Fall einen Unterschied für das Scheitern der Assertion anzeigt.

Wenn Sie assertFalse verwenden, erhalten Sie im Bericht lediglich einen Assertion-Fehler, d.h. Sie verlieren Informationen über die Ursache des Fehlers.

2voto

Willempie Punkte 103

Normalerweise mache ich das, wenn ich erwarte, dass zwei Objekte gleich sind:

assertTrue(obj1.equals(obj2));

und:

assertFalse(obj1.equals(obj2));

wenn man davon ausgeht, dass sie ungleich sind. Ich bin mir bewusst, dass dies keine Antwort auf Ihre Frage ist, aber es ist das, was ich am ehesten erreichen kann. Es könnte anderen helfen, die nach dem suchen, was sie in JUnit-Versionen vor JUnit 4.11 tun können.

0voto

davidxxx Punkte 114488

Ich stimme mit dem Standpunkt des Auftraggebers vollkommen überein. Assert.assertFalse(expected.equals(actual)) ist keine natürliche Art, eine Ungleichheit auszudrücken.
Ich würde jedoch behaupten, dass mehr als Assert.assertEquals() , Assert.assertNotEquals() funktioniert, aber es ist nicht benutzerfreundlich zu dokumentieren, was der Test tatsächlich behauptet und zu verstehen/debuggen, wenn die Behauptung fehlschlägt.
Also ja, JUnit 4.11 und JUnit 5 bieten Assert.assertNotEquals() ( Assertions.assertNotEquals() in JUnit 5), aber ich vermeide es wirklich, sie zu benutzen.

Alternativ dazu verwende ich für die Behauptung des Zustands eines Objekts in der Regel eine Matcher-API, die den Zustand des Objekts leicht ermitteln kann, die die Absicht der Behauptungen klar dokumentiert und die sehr benutzerfreundlich ist, um die Ursache für das Scheitern einer Behauptung zu verstehen.

Hier ist ein Beispiel.
Angenommen, ich habe eine Tierklasse, die ich testen möchte die createWithNewNameAndAge() Methode, eine Methode, die ein neues Tierobjekt erstellt, indem sie seinen Namen und sein Alter ändert, aber sein Lieblingsfutter beibehält.
Angenommen, ich verwende Assert.assertNotEquals() zu behaupten, dass das ursprüngliche und das neue Objekt unterschiedlich sind.
Hier ist die Klasse Animal mit einer fehlerhaften Implementierung von createWithNewNameAndAge() :

public class Animal {

    private String name;
    private int age;
    private String favoriteFood;

    public Animal(String name, int age, String favoriteFood) {
        this.name = name;
        this.age = age;
        this.favoriteFood = favoriteFood;
    }

    // Flawed implementation : use this.name and this.age to create the 
    // new Animal instead of using the name and age parameters
    public Animal createWithNewNameAndAge(String name, int age) {
        return new Animal(this.name, this.age, this.favoriteFood);
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getFavoriteFood() {
        return favoriteFood;
    }

    @Override
    public String toString() {
        return "Animal [name=" + name + ", age=" + age + ", favoriteFood=" + favoriteFood + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((favoriteFood == null) ? 0 : favoriteFood.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Animal)) return false;

        Animal other = (Animal) obj;
        return age == other.age && favoriteFood.equals(other.favoriteFood) &&
                name.equals(other.name);
    }

}

JUnit 4.11+ (oder JUnit 5) sowohl als Testläufer als auch als Assertion Tool

@Test
void assertListNotEquals_JUnit_way() {
    Animal scoubi = new Animal("scoubi", 10, "hay");
    Animal littleScoubi = scoubi.createWithNewNameAndAge("little scoubi", 1);
    Assert.assertNotEquals(scoubi, littleScoubi);
}

Der Test schlägt erwartungsgemäß fehl, aber die dem Entwickler mitgeteilte Ursache ist wirklich nicht hilfreich. Er sagt nur, dass die Werte unterschiedlich sein sollten und gibt die toString() Ergebnis, das auf dem aktuellen Animal Parameter :

java.lang.AssertionError: Werte sollten unterschiedlich sein. Tatsächlich: Tier

[name=scoubi, age=10, favoriteFood=heu]

at org.junit.Assert.fail(Assert.java:88)

Ok, die Objekte sind nicht gleichwertig. Aber wo ist das Problem?
Welches Feld wird bei der getesteten Methode nicht korrekt bewertet? Eins ? Zwei ? Alle ?
Um sie zu entdecken, muss man in der Erde graben createWithNewNameAndAge() Implementierung/einen Debugger verwenden, während die Test-API viel freundlicher wäre, wenn sie für uns den Unterschied zwischen dem, was erwartet wird und dem, was erhalten wird, machen würde.


JUnit 4.11 als Test-Runner und eine Test Matcher API als Assertion Tool

Hier das gleiche Szenario eines Tests, bei dem jedoch AssertJ (eine hervorragende Test-Matching-API) verwendet wird, um die Behauptung der Animal Zustand: :

import org.assertj.core.api.Assertions;

@Test
void assertListNotEquals_AssertJ() {
    Animal scoubi = new Animal("scoubi", 10, "hay");
    Animal littleScoubi = scoubi.createWithNewNameAndAge("little scoubi", 1);
    Assertions.assertThat(littleScoubi)
              .extracting(Animal::getName, Animal::getAge, Animal::getFavoriteFood)
              .containsExactly("little scoubi", 1, "hay");
}

Natürlich schlägt der Test immer noch fehl, aber dieses Mal wird der Grund klar angegeben:

java.lang.AssertionError:

Erwarten:

<["scoubi", 10, "Heu"]>

genau (und in der gleichen Reihenfolge) zu enthalten:

<["kleiner Scoubi", 1, "Heu"]>

aber einige Elemente wurden nicht gefunden:

<["kleiner Scoubi", 1]>

und andere wurden nicht erwartet:

<["scoubi", 10]>

at junit5.MyTest.assertListNotEquals_AssertJ(MyTest.java:26)

Wir können das lesen für Animal::getName, Animal::getAge, Animal::getFavoriteFood Werte des zurückgegebenen Tieres, so erwarten wir diese Werte:

"little scoubi", 1, "hay" 

aber wir haben diese Werte gehabt:

"scoubi", 10, "hay"

Wir wissen also, wo die Ermittlungen stattfinden: name y age nicht korrekt bewertet werden. Außerdem ist die Tatsache, dass die Angabe der hay Wert in der Behauptung von Animal::getFavoriteFood() erlaubt es auch, die zurückgegebenen Daten feiner Animal . Wir wollen, dass die Objekte für einige Eigenschaften nicht gleich sind, aber nicht unbedingt für alle Eigenschaften.
Die Verwendung einer Matcher-API ist also auf jeden Fall viel klarer und flexibler.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X