@BITniki

Как тестировать работу Service класса с базой данных или как сравнить два JPA entity объекта в тестах?

Есть у меня `UserService` класс, в котором есть метод:
public Spliterator<UserEntity> getAll() {
        return userRepo.findAll().spliterator();
}

К этому методу я хочу написать тест. В тестах у меня подтягивается тестовая база данных, так что я точно знаю, что этот метод должен вернуть. Поэтому мой тест имеет вид:
@Test
public void testFindAllUsers() {
    // Create model
    List<UserEntity> modelList = List.of(
            UserEntity.builder().id(1L).login("test").password("aA123456").build(),
            UserEntity.builder().id(2L).login("test2").password("aA123456").build()
    );
    // Get result
    List<UserEntity> resultList = StreamSupport.stream(userService.getAll(), false)
            .toList();
    
    // Compare
    // ...
}


Собственно весь мой вопрос заключается в реализации этапа "Compare".
Сначала решил реализовать equals() в UserEntity:
/**
* Cтандартная реализация equals() от IntelliJ IDEA. В Lombok похожая реализация
*/
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    UserEntity entity = (UserEntity) o;
    if (getId() != null ? !getId().equals(entity.getId()) : entity.getId() != null) return false;
    if (getLogin() != null ? !getLogin().equals(entity.getLogin()) : entity.getLogin() != null) return false;
    if (getPassword() != null ? !getPassword().equals(entity.getPassword()) : entity.getPassword() != null)
        return false;
    //...
}

Но если сравнивать все поля, то будут потягиваться все lazy поля, на что все в этих ваших интернетах ругаются, что так нельзя реализовывать equals().
Далее я решил сравнивать по полям прям в тесте.:
// Compare
for (int i = 0; i < modelList.size(); i++) {
    var model = modelList.get(i);
    var result = modelList.get(i);
    assertEquals(model.getId(), result.getId());
    assertEquals(model.getLogin(), result.getLogin());
    assertEquals(model.getPassword(), result.getPassword());
}

Но это как-то слишком в лоб и не элегантно.
Есть ли способ лучше?
  • Вопрос задан
  • 43 просмотра
Пригласить эксперта
Ответы на вопрос 2
@serser120
Расскажу на примере своего метода из сервиса, который возвращает список видео. В VideoTestData у меня просто прописаны клише сущностей/списков и тд
Используй import org.mockito.Mockito;

protected void getAll() {
//в тестируемом методе идет вызов метода репозитория, через when прописываем, что должно вернуться
Mockito.when(videoRepository.findAll()).thenReturn(VideoTestData.VIDEO_LIST);
//аналогично прописываем что должно передаться и вернуться, это надо сделать для каждого действия в методе //сервиса, где мы тыкаемся куда-то за его пределы(в репозиторий, маппер и тд)
Mockito.when(videoMapper.toDTOs(VideoTestData.VIDEO_LIST)).thenReturn(VideoTestData.VIDEO_DTO_LIST);
//тут мы вызываем непосредственно нужный метод и записываем результат
List videoDTOS = service.listAll();
//тут сравниваем полученный результат с ожидаемым
assertEquals(VideoTestData.VIDEO_LIST.size(), videoDTOS.size());
}

надеюсь смог помочь, успехов!
Ответ написан
Комментировать
@Wan-Derer
Зобанели на Хабре, волки́ ;((
Когда ты реализуешь equals() и hashCode(), логику этих методов ты определяешь сам, тебе не обязательно сравнивать все поля. Сравнивать то что тебе надо и так как надо - хоть фазу Луны со спином ретроградного Меркурия.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы