Pregunta

¿Alguien sabe por qué JUnit 4 proporciona assertEquals(foo,bar) pero no assertNotEqual(foo,bar) métodos?

Proporciona assertNotSame (correspondiente a assertSame) y assertFalse (correspondiente a assertTrue), por lo que parece extraño que no se molestaron incluyendo assertNotEqual.

Por cierto, sé que JUnit-addons proporciona los métodos que estoy buscando. Sólo pregunto por curiosidad.

¿Fue útil?

Solución

Yo te sugeriría que utiliza el assertThat() nuevo estilo afirma, lo que puede describir fácilmente todo tipo de negaciones y construir automáticamente una descripción de lo que se esperaba y lo que tienes si falla la aserción:

assertThat(objectUnderTest, is(not(someOtherObject)));
assertThat(objectUnderTest, not(someOtherObject));
assertThat(objectUnderTest, not(equalTo(someOtherObject)));

Las tres opciones son equivalentes, elija el que le resulte más fácil de leer.

Para utilizar los nombres simples de los métodos (y permitir que esta sintaxis tensa al trabajo), necesita estas importaciones:

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

Otros consejos

Hay un assertNotEquals en JUnit 4,11: https://github.com/junit-team/junit/blob/master/doc/ReleaseNotes4.11.md#improvements-to-assert-and-assume

import static org.junit.Assert.assertNotEquals;

Me pregunto misma. La API de aserción no es muy simétrica; Para la prueba de si los objetos son los mismos, proporciona assertSame y assertNotSame.

Por supuesto, no es demasiado tiempo para escribir:

assertFalse(foo.equals(bar));

Con tal afirmación, la única parte informativa de la salida es por desgracia el nombre del método de ensayo, el mensaje así descriptiva debe ser formado por separado:

String msg = "Expected <" + foo + "> to be unequal to <" + bar +">";
assertFalse(msg, foo.equals(bar));

Esto es, por supuesto, tan aburrido, que es mejor para rodar su propia assertNotEqual. Por suerte en el futuro será tal vez ser parte de la JUnit: tema JUnit 22

Yo diría que la ausencia de assertNotEqual es de hecho una asimetría y hace JUnit un poco menos puede aprender. Cuenta que este es un caso limpio cuando se añade un método disminuiría la complejidad de la API, al menos para mí: Simetría ayuda a gobernar el espacio más grande. Mi conjetura es que la razón de la omisión puede ser que hay muy pocas personas que llaman para el método. Sin embargo, recuerdo un momento en que no existía aún assertFalse; por lo tanto, tengo una expectativa positiva de que el método podría eventualmente ser añadido, dado que no es difícil; Aunque reconozca que existen numerosas soluciones alternativas, incluso las más elegantes.

Voy a ir a este partido bastante tarde, pero he encontrado que la forma:

static void assertTrue(java.lang.String message, boolean condition) 

se pueden hacer funcionar para la mayoría 'no igual a' casos.

int status = doSomething() ; // expected to return 123
assertTrue("doSomething() returned unexpected status", status != 123 ) ;

Estoy trabajando en JUnit en Java 8 ambiente, utilizando jUnit4.12

para mí: compilador no fue capaz de encontrar las assertNotEquals método, aun cuando solía
    import org.junit.Assert;

Así que cambié
assertNotEquals("addb", string);
a
Assert.assertNotEquals("addb", string);

Así que si se enfrentan a un problema con respecto assertNotEqual no se reconoce, a continuación, cambiar a Assert.assertNotEquals(,); debe resolver su problema

La razón obvia que la gente quería assertNotEquals () fue comparar órdenes internas sin tener que convertirlos en objetos plena soplado primeros:

ejemplo detallado:

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

vs.

assertNotEqual(1, winningBidderId);

Lamentablemente desde Eclipse no incluye JUnit 4.11 por defecto debe ser detallada.

Advertencia No creo que el '1' tiene que ser envuelto en una Integer.valueOf (), pero ya que estoy recién regresé de .NET no contar con mi corrección.

Es mejor utilizar el Hamcrest para las negativas en lugar de assertFalse como en el primero, el informe de la prueba será mostrar un resumen para el error de aserción.

Si utiliza assertFalse, que acaba de obtener un error de aserción en el informe. es decir perdido información sobre la causa de la falla.

Estoy totalmente de acuerdo con el punto de vista OP. Assert.assertFalse(expected.equals(actual)) no es una forma natural de expresar una desigualdad.
Pero yo diría que más allá de Assert.assertEquals(), obras Assert.assertNotEquals() pero no es fácil de usar para documentar lo que la prueba de hecho afirma y entender / depuración que falla la aserción.
Así que sí JUnit JUnit 4.11 y 5 proporciona Assert.assertNotEquals() (Assertions.assertNotEquals() en JUnit 5) pero realmente evitar el uso de ellos.

Como alternativa, afirmar el estado de un objeto general uso un API de coincidencias que se clava en el estado del objeto con facilidad, ese documento claramente la intención de las afirmaciones y que es muy fácil de usar para entender la causa del error de aserción.

A continuación se muestra un ejemplo.
Supongamos que tengo una clase de animal que quiero probar el método createWithNewNameAndAge(), un método que crea un nuevo objeto de animales, cambiando su nombre y su edad, pero manteniendo su comida favorita.
Supongamos que yo utilizo Assert.assertNotEquals() afirmar que el original y los nuevos objetos son diferentes.
Esta es la clase de animal con una aplicación defectuosa de 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+ (o JUnit 5) tanto como corredor de prueba y una herramienta de afirmación

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

La prueba falla como se esperaba, pero la causa proporcionada al desarrollador de verdad no es útil. Sólo dice que los valores deben ser diferentes y enviar el resultado toString() invocado en el parámetro Animal real:

  

java.lang.AssertionError: Los valores deben ser diferentes. Real: Animal

     

[name = scoubi, edad = 10, favoriteFood = heno]

     

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

Aceptar los objetos no son iguales. Pero ¿dónde está el problema?
El campo que no se valora correctamente en el método de la prueba? Uno ? Dos? Todos ellos?
Para descubrir que usted tiene que cavar en la implementación createWithNewNameAndAge() / usar un depurador mientras que el API de prueba sería mucho más agradable si se haría para nosotros el diferencial entre las que se espera y que está metido.


JUnit 4,11 como corredor de prueba y una API Matcher prueba como herramienta de afirmación

A continuación, el mismo escenario de prueba, sino que utiliza AssertJ (una excelente API coincidencias de prueba) para hacer la afirmación del estado Animal::

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");
}

Por supuesto, la prueba todavía falla, pero esta vez la razón se afirma claramente:

  

java.lang.AssertionError:

     

Esperando:

     

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

     

para contener exactamente (y en mismo orden):

     

<[ "poco scoubi", 1, "hay"]>

     

pero no se encontraron algunos elementos:

     

<[ "poco scoubi", 1]>

     

y otros no se esperaba:

     

<[ "scoubi", 10]>

     

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

Podemos leer que para valores Animal::getName, Animal::getAge, Animal::getFavoriteFood del animal regresado, esperamos tener estos valores:

"little scoubi", 1, "hay" 

pero hemos tenido estos valores:

"scoubi", 10, "hay"

Así que sabemos donde investigar: name y age no se valoran correctamente. Además, el hecho de especificar el valor hay en la afirmación de Animal::getFavoriteFood() permite también hacer valer más finamente la Animal devuelto. Queremos que los objetos no sean los mismos para algunas propiedades, pero no necesariamente para cada propiedades.
Así que definitivamente, mediante una API de coincidencias es mucho más claro y flexible.

Modulo consistencia API, por eso JUnit no proporcionó assertNotEquals() es la misma razón por la JUnit nunca proporcionó métodos como

  • assertStringMatchesTheRegex(regex, str) vs assertStringDoesntMatchTheRegex(regex, str)
  • assertStringBeginsWith(prefix, str) vs assertStringDoesntBeginWith(prefix, str)

es decir. no hay fin de proporcionar una afirmación métodos específicos para el tipo de cosas que usted podría querer en la lógica de la afirmación!

Es mucho mejor para proporcionar primitivas de prueba componibles como equalTo(...), is(...), not(...), regex(...) y dejar que la pieza programador aquellos juntos en lugar de más legibilidad y la cordura.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top