1. 무슨 문제가 있었는지?
현재 프로젝트 환경은 SpringSecurity를 통해 사용자를 인증하고 JpaAuditing 기능을 통해 {생성한 사람, 생성일, 수정한 사람, 수정일} 을 자동으로 주입해주고 있다. JpaAuditing 기능을 적용하면서 기존에 {생성한 사람, 생성일, 수정한 사람, 수정일} 에 대해 직접 설정했던 코드를 제거하였는데 이후 데이터를 저장하는 단위 테스트에서 아래와 같은 오류가 발생하였다.
could not execute statement [Column 'create_user' cannot be null]
2. 문제의 원인은?
JpaAuditing 을 도입하면서 기존에 {생성한 사람, 생성일, 수정한 사람, 수정일} 에 대해 직접 설정했던 코드를 제거하였고 아래와 같이 Spring Security의 사용자 정보를 이용하여 위의 값을 설정하고 있다.
하지만 테스트 환경에서는 Spring Security를 통해 사용자 설정을 하지 않은 상태이기 때문에 데이터를 저장하는 시점에 유저 정보가 null 값으로 설정되어 오류가 발생하는 것이였다.
3. 해결방법
공식 홈페이지를 찾아보니 @WithMockUser, @WithAnonymousUser, @WithUserDetails, @WithSecurityContext 를 이용하여 설정하는 방법을 알려주고 있었다. 모두 처음보는 어노테이션이라 정리가 필요할 것 같은데 이 부분은 다른 포스팅을 통해 진행할 것 같다.
먼저 문제 해결을 위해 @WithMockUser 어노테이션을 다음과 같이 사용했다. 해당 어노테이션을 클래스 단위로 적용했지만 각 단위 테스트 메서드별로 적용이 가능하다. 어노테이션을 적용하고 난 후 단위 테스트를 깔끔하게 통과한다.
@SpringBootTest
@WithMockUser(username="test", password="test", roles = {"USER"})
class MyTest {
// ...
}
4. 배운점
- 단위 테스트에서 Spring Security 의 사용자 설정을 적용하는 방법
- 각 어노테이션의 사용법( @WithMockUser, @WithAnonymousUser, @WithUserDetails, @WithSecurityContext )
5. 출처
https://docs.spring.io/spring-security/reference/servlet/test/method.html
Testing Method Security :: Spring Security
If you reuse the same user within your tests often, it is not ideal to have to repeatedly specify the attributes. For example, if you have many tests related to an administrative user with a username of admin and roles of ROLE_USER and ROLE_ADMIN, you have
docs.spring.io