У меня есть класс БД, который помечен @Entity в Java.
Я хочу сравнить 2 экземпляра класса, поле которого я хочу сравнить по полям, но получаю ошибку от Hamcrest, что объекты не равны. Он сохраняется, если я автоматически не сгенерирую equals и hashCode в Eclipse.
Структура сущности следующая:
@Entity
@Table(name = "book")
public class Book extends BaseEntity {
@NotNull
@Column
private String title;
}
и
@MappedSuperClass
class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
}
Для простоты я опустил все геттеры и сеттеры.
Пример кода, как я использую сущность выше:
public void updateBookTitles(bookIds) {
List<Book> books = bookRepository.findByBookIds(bookIds);
books.forEach((book) -> {
book.setTitle("Example: " + book.getTitle());
});
bookRepository.saveAll(books);
}
При тестировании этого:
@Test
public void updateSingleBookTitle() {
Book book = new Book();
book.setId(1L);
book.setTitle("Stack Overflow manual");
when(bookRepository.findByBookIds(Arrays.asList(1L))).thenReturn(Arrays.asList(book));
updateBookTitles(Arrays.asList(1L));
Book expectedBook = new Book();
expectedBook.setId(1L);
expectedBook.setTitle("Stack Overflow manual");
verify(bookRepository, times(1)).saveAll(Arrays.asList(expectedBook))
}
Поэтому вопрос у меня. Есть ли способ, кроме автогенерации equals и hashCode, чтобы объекты были равны при тестировании, а также, чтобы не снижалась производительность при сохранении в БД. Насколько я понимаю, на данный момент объекты проверяются по полю id не по всем полям.




Вы можете использовать что-то вроде Lombok https://projectlombok.org/ для таких объектов данных. Как и равные, hashCode, геттеры и сеттеры.
Вы можете использовать метод samePropertyValuesAs:
Book book1 = new Book();
Book book2 = new Book();
assertThat(book1, samePropertyValuesAs(book2));
Это будет сравнивать ваши объекты поле за полем и выполнять утверждения об их равенстве друг другу. Если вам нужно игнорировать какие-то поля - смотрите Shazamcrest — многоразовые сопоставители Hamcrest, подходящие для автоматизированного тестирования.
ОБНОВЛЕНИЕ 1:
Попробуйте использовать следующий код:
verify(bookRepository, times(1)).saveAll(argThat(new ArgumentMatcher<List<Book>>() {
@Override
public boolean matches(Object argument) {
List<Book> bookToCheck = (List<Book>) argument;
assertThat(bookToCheck.get(0), sameAsBean(expectedBook));
return true;
}
}));
Дополнительная информация : ArgumentMatcher
добавьте пример кода, где создайте/сравните эти объекты