BackEnd/TDD

[junit5] MockMvc에서 NestedServletException 통과시키기

샤아이인 2022. 3. 11.

직접 경함한 오류를 해결한 과정을 정리한 글 입니다.

 

1. 상황

우선 저의 코드에서 UserService는 인자로 받은 userId로 회원을 찾아보는데, 이때  만약 회원이 없다면 예외를 던지게 됩니다.

@Service
public class UserService {
    private final UserRepository repository;

    public UserService(UserRepository repository) {
        this.repository = repository;
    }
    
    // 생략...

    public User findUserById(String userId) {
        return repository.findById(userId)
                .orElseThrow(() -> new NotFoundException(USER_NOT_FOUND_EXCEPTION));
    }
    
    public boolean userUpdate(User user) {
        User findUser = findUserById(user.getUserId());

        if (findUser.isSamePassword(user.getPassword())) {
            return repository.update(user.getUserId(), user);
        }

        return false;
    }
}

 

이 userSerivce를 활용하는 test code는 다음과 같습니다.

    @Test
    public void updateFailTest() throws Exception {
        // given
        given(userService.userUpdate(any())).willThrow(new NotFoundException("해당 사용자를 찾을 수 없습니다"));

        // when
        ResultActions actions = mockMvc.perform(post("/users/" + user.getUserId() + "/update")
                .param("userId", "Shine")
                .param("password", "1234")
                .param("name", "Shine")
                .param("email", "shine@naver.com")
                .accept(MediaType.TEXT_HTML)
        );

        // then
        actions.andExpect(status().is4xxClientError())
                .andExpect(
                        // assert로 예외를 검사하는 람다 사용
                        (rslt) -> assertTrue(rslt.getResolvedException().getClass().isAssignableFrom(NotFoundException.class))
                );
    }

mockMvc 로 perform 을 통해 post 메서드를 전송하고, 이때 userUpdate() 메서드를 호출하면서 userUpdate() 내부의 findUserById를 호출하게 됩니다.

 

이때 throw new NotFoundException("~~"); 를 발생시키면 mockmvc 테스트 도중 NestedServletException 이 발생합니다.

따라서 테스트를 실패하게 된다.

 

junit5에서 다음과 같은 방법으로 NestedServletException 내부에서 발생한 exception을 검사할 수 있도록 다음과 같은 메서드를 제공하고 있습니다!

Assertions.assertThatThrownBy(() -> mockMvc.perform(post("/users/" + user.getUserId() + "/update")
        .param("userId", "Shine")
        .param("password", "1234")
        .param("name", "Shine")
        .param("email", "shine@naver.com")
        .accept(MediaType.TEXT_HTML)
)).hasCause(new NotFoundException("해당 사용자를 찾을 수 없습니다"));

 

https://stackoverflow.com/questions/44900646/how-to-prevent-nestedservletexception-when-testing-spring-endpoints

 

How to prevent NestedServletException when testing Spring endpoints?

I am trying to test the security configuration of some of my endpoints which are secured with @PreAuthorize(#oauth2.hasScope('scope'). When accessing such an endpoint via Postman with a access toke...

stackoverflow.com

 

댓글