Почему JUnit не предоставляет методы assertNotEquals?
кто-нибудь знает, почему JUnit 4 предоставляет assertEquals(foo,bar) а не assertNotEqual(foo,bar) методами?
обеспечивает assertNotSame (соответствует assertSame) и assertFalse (соответствует assertTrue), поэтому кажется странным, что они не потрудились включить assertNotEqual.
кстати, я знаю, что JUnit-addons предоставляет методы, которые я ищу. Я просто спрашиваю из любопытства.
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-assumeimport 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-интерфейс для сопоставления тестов), чтобы сделать утверждение
Animalstate::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