Я также столкнулся с этим вопросом в прошлом, и я полностью согласен с вы, что реализация equals()
и hashCode()
только для целей тестирования - это запах кода. Я не использую библиотеку Hamcrest, поэтому я дам вам специальное решение, которое я успешно использую в своих проектах, и что касается его использования, я им очень доволен.
public static <E, A> void assertListEquals(BiConsumer<E, A> asserter, List<E> expected, List<A> actual) throws AssertionError {
assertEquals(
"Lists have different sizes. Expected list: " + expected + ", actual list: " + actual,
expected.size(),
actual.size());
for (int i = 0; i < expected.size(); i++) {
try {
asserter.accept(expected.get(i), actual.get(i));
} catch (AssertionError e) {
throw e;
}
}
}
Как вы можете видеть, BiConsumer используется для того, чтобы применить логику для проверки равенства двух объектов. Таким образом, этот должен быть реализован в тестовом классе. Преимущество этого в том, что вы можете определить поля интересующего вас класса при сравнении двух объектов.
Посмотрите на использование: Сначала у нас есть пользовательский класс, f.e.: Человек
public class Person {
private String firstName;
private String lastName;
private int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
}
Тогда давайте посмотрим, метод испытания:
@Test
public void peopleLiveInTheVillage_findPeople_peopleAreFound() throws Exception {
//Arrange
List<Person> expectedPeople = Arrays.asList(
new Person("Lewis", "Smith", 20),
new Person("Steven", "Richard", 25),
new Person("Richie", "Rich", 30));
//Act
List<Person> actualPeople = sut.findPeople();
//Assert
assertListEquals(
(e, a) -> assertPersonEquals(e, a),
expectedPeople,
actualPeople);
}
private void assertPersonEquals(Person expected, Person actual) {
assertEquals(expected.getFirstName(), actual.getFirstName());
assertEquals(expected.getLastName(), actual.getLastName());
assertEquals(expected.getAge(), actual.getAge());
}
Поскольку я большой поклонник тестов (и TDD) Я всегда пишу тонны тестов, так что я всегда делаю вспомогательный метод, где я оберните BiConsumer:
private void assertPeopleEqual(List<Person> expectedPeople, List<Person> actualPeople) throws AssertionError {
assertListEquals(
(e, a) -> assertPersonEqual(e, a),
expectedPeople,
actualPeople);
}
Надеюсь, это поможет, ура!
Думаю, я бы добавил, что нет причин, по которым вы не могли бы использовать 'ReflectionEquals' в методе' matchesSafely' 'Matcher' –