assertEquals(Object, Object)
из JUnit4 / JUnit 5 или assertThat(actual, is(expected));
из Hamcrest, предложенные в других ответах, будут работать только в том случае, если и equals()
, и toString()
переопределены для классов (и глубоко) сравниваемых объектов.
Это важно, потому что проверка на равенство в утверждении опирается на equals()
, а сообщение об ошибке теста - на toString()
сравниваемых объектов.
Для встроенных классов, таких как String
, Integer
и т. Д. Для ... нет проблем, поскольку они переопределяют как equals()
, так и toString()
. Так что совершенно справедливо утверждать List<String>
или List<Integer>
с assertEquals(Object,Object)
.
И по этому поводу: вы должны переопределить equals()
в классе, потому что это имеет смысл с точки зрения равенства объектов, а не только для упрощения утверждений в тесте с JUnit.
Чтобы сделать утверждения проще, у вас есть другие способы.
В качестве хорошей практики я предпочитаю библиотеки утверждений / сопоставлений.
Вот решение AssertJ .
org.assertj.core.api.ListAssert.containsExactly()
- это то, что вам нужно: он проверяет, что фактическая группа содержит именно заданные значения и ничего больше, в порядке, указанном в javadoc.
Предположим, класс Foo
, где вы добавляете элементы и где вы можете получить это.
Модульный тест Foo
, который утверждает, что два списка имеют одинаковое содержимое, может выглядеть следующим образом:
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
@Test
void add() throws Exception {
Foo foo = new Foo();
foo.add("One", "Two", "Three");
Assertions.assertThat(foo.getElements())
.containsExactly("One", "Two", "Three");
}
Хорошая мысль AssertJ заключается в том, что объявление List
как и положено не нужно: это делает утверждение более прямым и код более читабельным:
Assertions.assertThat(foo.getElements())
.containsExactly("One", "Two", "Three");
Но библиотеки Assertion / matcher обязательны, потому что они действительно будут дальше.
Предположим теперь, что Foo
хранит не String
с, а Bar
с.
Это очень распространенная потребность.
С AssertJ утверждение все еще просто написать. Лучше утверждать, что содержимое списка равно, даже если класс элементов не переопределяет equals()/hashCode()
, в то время как JUnit требует, чтобы:
import org.assertj.core.api.Assertions;
import static org.assertj.core.groups.Tuple.tuple;
import org.junit.jupiter.api.Test;
@Test
void add() throws Exception {
Foo foo = new Foo();
foo.add(new Bar(1, "One"), new Bar(2, "Two"), new Bar(3, "Three"));
Assertions.assertThat(foo.getElements())
.extracting(Bar::getId, Bar::getName)
.containsExactly(tuple(1, "One"),
tuple(2, "Two"),
tuple(3, "Three"));
}