Как лечить исключение UserNotFound в модульных тестах конечных точек? - PullRequest
0 голосов
/ 17 июня 2020

Я работаю над Spring Boot CRUD RESTful API с сущностью User , которая состоит из двух параметров: name и id. Моя тестовая среда - JUnit .

Проблема, с которой я сталкиваюсь, заключается в том, что я не знаю, как лечить исключение UserNotFound в моих модульных тестах служб.

У меня есть возможные «Пользователь не найден по {id}» исключения в моем «Список пользователей по идентификатору» , «Удалить пользователя по идентификатору» и «Обновить пользователя по идентификатору» как вы можете видеть (я перечислю только две конечные точки, чтобы сделать это короче):

@Service
public class DeleteUserService {

    @Autowired
    UserRepository repository;

    public void deleteUser(Long id) {
        Optional<User> userOptional = repository.findById(id);
        if (!userOptional.isPresent()) {
            throw new UserNotFoundException(id);
        } else {
            repository.deleteById(id);
        }
    }
}

@Service
public class DetailUserService {

    @Autowired
    UserRepository repository;

    public Optional<User> listUser(Long id) {

        Optional<User> user = repository.findById(id);
        if (!user.isPresent()) {
            throw new UserNotFoundException(id);
        } else {
            return repository.findById(id);
        }
    }
}

Пока ничего плохого, мои конечные точки работает нормально. Код UserNotFound :

@ControllerAdvice
public class UserNotFoundAdvice {

    @ResponseBody
    @ExceptionHandler(UserNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    String userNotFoundHandler(UserNotFoundException ex) {
        return ex.getMessage();
    }
}

public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(Long id) {
        super("Could not find user with id " + id + ".");
    }
}

Модульные тесты (основная причина, по которой это пишется):

@RunWith(MockitoJUnitRunner.class)
public class DeleteUserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private DeleteUserService deleteUserService;

    @Test
    public void whenGivenId_shouldDeleteUser_ifFound(){
        User user = new User();
        user.setId(89L);

        deleteUserService.deleteUser(user.getId());
        verify(userRepository).deleteById(user.getId());
    }
}

@RunWith(MockitoJUnitRunner.class)
public class DetailUserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private DetailUserService detailUserService;

    @Test
    public void whenGivenId_shouldReturnUser_ifFound() {
        User user = new User();
        user.setId(89L);

        Optional<User> userMock = Optional.of(user);

        when(userRepository.findById(user.getId())).thenReturn(userMock);

        Optional<User> expected = detailUserService.listUser(user.getId());

        assertThat(expected).isSameAs(userMock);
        verify(userRepository).findById(user.getId());
    }
}

Как видите, чего-то не хватает в этих модульных тестах код, который является поведением UserNotFound . Возможно, это неправильно или что-то еще отсутствует в коде модульных тестов ??

Был бы очень признателен, если бы кто-нибудь мог мне помочь с этим! Извините, если пост слишком длинный, я изо всех сил старался его объяснить!

1 Ответ

0 голосов
/ 17 июня 2020

Если я вас правильно понимаю, вам нужно протестировать поведение, когда пользователь не найден и вы генерируете исключение.

Вот ссылка о том, как протестировать исключение: https://www.baeldung.com/junit-assert-exception

А также, кроме того, вы можете проверить, что удаление по идентификатору или поиск по идентификатору не вызывались:

verify(userRepository, never()).findById(user.getId()); 
or
verify(userRepository, Mockito.times(0)).findById(user.getId());

и для deleteById то же самое

Чтобы проверить, что обработчики исключений были вызваны и работали правильно, вам нужны интеграционные тесты.

...