Почему JUnit не предоставляет методы assertNotEquals?



кто-нибудь знает, почему JUnit 4 предоставляет assertEquals(foo,bar) а не assertNotEqual(foo,bar) методами?



обеспечивает assertNotSame (соответствует assertSame) и assertFalse (соответствует assertTrue), поэтому кажется странным, что они не потрудились включить assertNotEqual.



кстати, я знаю, что JUnit-addons предоставляет методы, которые я ищу. Я просто спрашиваю из любопытства.

741   10  

10 ответов:

Я бы предложил вам использовать более новый assertThat() стиль утверждает, что может легко описать все виды отрицаний и автоматически построить описание того, что вы ожидали и что вы получили, если утверждение не удается:

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

все три варианта эквивалентны, выберите тот, который вы считаете наиболее читаемым.

чтобы использовать простые имена методов (и позволить этому напряженному синтаксису работать), вам нужны следующие импорта:

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

есть assertNotEquals в 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;

Я бы сказал, что отсутствие assertNotEqual действительно является асимметрией и делает JUnit немного менее изучаемым. Имейте в виду, что это аккуратный случай, когда добавление метода уменьшит сложность API, по крайней мере для меня: симметрия помогает управлять большим пространством. Я предполагаю, что причиной упущения может быть то, что слишком мало людей, вызывающих этот метод. Тем не менее, я помню время, когда даже assertFalse не существовало; следовательно, у меня есть положительное ожидание, что метод может в конце концов, добавлю, учитывая, что это не сложно; хотя я признаю, что есть множество обходных путей, даже элегантных.

Я иду на эту вечеринку довольно поздно, но я обнаружил, что в форме:

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

можно заставить работать для большинства случаев "не равно".

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

очевидная причина, по которой люди хотели assertNotEquals (), состояла в том, чтобы сравнить встроенные файлы без необходимости сначала конвертировать их в полномасштабные объекты:

подробный пример:

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

и

assertNotEqual(1, winningBidderId);

к сожалению, поскольку Eclipse не включает JUnit 4.11 по умолчанию, вы должны быть подробными.

предостережение я не думаю, что '1' должен быть завернут в целое число.valueOf () но так как я недавно вернулся из .NET, не рассчитывайте на мою правильность.

Я работаю над JUnit в среде java 8, используя jUnit4. 12

для меня: компилятор не смог найти метод assertNotEquals, даже когда я использовал
import org.junit.Assert;

так я изменился
assertNotEquals("addb", string);
до
Assert.assertNotEquals("addb", string);

так что если вы столкнулись с проблемой относительно assertNotEqual не распознается, затем измените его на Assert.assertNotEquals(,); это должно решить вашу проблему.

лучше использовать Hamcrest для отрицательных утверждений, а не assertFalse, как в первом отчете об испытаниях будет показано различие для отказа утверждения.

Если вы используете assertFalse, вы просто получаете ошибку утверждения в отчете. т. е. утеряна информация о причине сбоя.

я полностью согласен с точкой зрения ОП. Assert.assertFalse(expected.equals(actual)) - это не естественный способ выразить неравенством.
Но я бы сказал, что дальше, чем Assert.assertEquals(),Assert.assertNotEquals() работает, но не является удобным для пользователя, чтобы документировать то, что тест фактически утверждает и понимать/отлаживать, поскольку утверждение терпит неудачу.
Так что да JUnit 4.11 и JUnit 5 обеспечивает Assert.assertNotEquals() (Assertions.assertNotEquals() в JUnit 5) но я действительно избегаю их использования.

в качестве альтернативы, чтобы утверждать состояние объекта я обычно использую a matcher API, который легко проникает в состояние объекта, этот документ четко определяет намерение утверждений и очень удобен для пользователя, чтобы понять причину сбоя утверждения.

вот пример.
Предположим у меня есть класс животных, который я хочу проверить createWithNewNameAndAge() метод, метод, который создает новый объект животного путем изменения его имени и возраста, но сохраняя свою любимую пищу.
Предположим, я использую Assert.assertNotEquals() утверждать, что исходные и новые объекты различаться.
Вот класс животных с ошибочной реализацией 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+ (или JUnit 5) как тестовый бегун, так и инструмент утверждения

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

тест завершается неудачей, как и ожидалось, но причина, предоставленная разработчику, действительно не помогает. Он просто говорит, что значения должны быть разными и выводить toString() результат вызывается на фактическом :

java.ленг.AssertionError: значения должны быть разными. Актуально: Животное

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

в орг.тесты JUnit.Утверждать.провал(утверждать.Ява:88)

Ok объекты не равны. Но в чем же проблема ?
Какое поле не правильно оценено в тестируемом методе ? Один ? Два ? Все они ?
Чтобы обнаружить его, вы должны копать в createWithNewNameAndAge() реализация / использование отладчика при тестировании API было бы гораздо более дружелюбно, если бы это сделало для нас разницу между ожидаемым и полученным.


JUnit 4.11 как тестовый бегун и API-интерфейс сопоставления тестов как инструмент утверждения

здесь тот же сценарий теста, но который использует AssertJ (отличный API-интерфейс для сопоставления тестов), чтобы сделать утверждение Animal state::

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

конечно, тест все еще не удается, но на этот раз причина четко указана :

java.ленг.AssertionError:

ожидаем:

содержат именно (и в том же порядке):

но некоторые элементы не были обнаружены:

и другие не ожидались:

at junit5.Мой самый лучший.assertListNotEquals_AssertJ(MyTest.Ява:26)

мы можем прочитать, что для Animal::getName, Animal::getAge, Animal::getFavoriteFood значения возвращенного животного, мы ожидаем, что они будут иметь следующее значение:

"little scoubi", 1, "hay" 

но у нас были такие значения:

"scoubi", 10, "hay"

Итак, мы знаем, где исследуют : name и age не правильно оценены. Кроме того, факт указания hay значение в утверждении Animal::getFavoriteFood() позволяет также более точно утверждать, возвращенный Animal. Мы хотим, чтобы объекты не были одинаковыми для некоторых свойств, но не обязательно для всех свойств.
Поэтому, безусловно, использование API-интерфейса matcher намного более ясно и гибко.

согласованность API по модулю, почему JUnit не предоставил assertNotEquals() Это та же причина, почему JUnit никогда не предоставлял такие методы, как

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

т. е. нет конца предоставлению конкретных методов утверждения для тех вещей, которые вы можете захотеть в своей логике утверждений!

гораздо лучше предоставить составные тестовые примитивы, такие как equalTo(...),is(...),not(...),regex(...) и пусть программист соединяет их вместе вместо этого для большей читаемости и здравомыслия.

Comments

    Ничего не найдено.