728x90
반응형
스프링에서 Mock을 활용한 테스트를 할 때, Mockito를 가장 많이 사용할 것이다. 그리고 검증 로직을 만들 때 호출 횟수 기준으로 테스트 코드를 짜는 경우가 있다.
// when
userService.create(userSignUpRequest)
// then
verify(userRepository, times(1)).save(any<User>())
verify(emailSender, only()).send(any(), any())
처음에는 2가지 모두 1회만 사용한다는 점에서 동일한 용도가 아닐까 했다. 즉 아래와 같다.
// userRepository라는 Mock bean은 save를 1회만 호출한다
verify(userRepository, times(1)).save(any<User>())
// emailSender라는 Mock bean은 send를 1회만 호출한다
verify(emailSender, only()).send(any(), any())
그렇다면 times를 사용한 부분을 only로 바꿔도 되지 않을까? 그렇게 생각해서 변경했더니 아래와 같은 에러가 나타났다. 왜 이런 에러가 나타날까?
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
Cannot invoke "org.mockito.invocation.Invocation.getMock()" because "undesired" is null
java.lang.NullPointerException: Cannot invoke "org.mockito.invocation.Invocation.getMock()" because "undesired" is null
이유는 times(1)와 only은 용도의 차이가 있기 때문이다.
- times(1)는 원래 생각했던 것처럼 해당 mock bean의 method를 1회만 호출한다는 의미가 맞다.
- only은 해당 mock bean에서 오로지 지정된 method만 호출하는지 확인하는 의도를 가진다.
when 구문의 userService.create 로직을 살펴보자.
fun creaet(request: UserSignUpRequest) {
userRepository.findByUsername(username)?.let {
throw DuplicateUsernameException() // Custome하게 만든 Exception
}
val user = User.create(request)
userRepository.save(user)
emailSender.send(user, request)
}
userRepository는 2번의 사용(findByUsername, save)이 있었다. 그래서 원하는 method의 횟수 검증을 하려면 only을 사용할 수 없고 times를 사용해야한다. 하지만 emailSender는 오로지 send 함수만 사용한다. 해당 Bean이 단 하나의 함수만 사용하는지 검증하기 위해 only을 사용할 수 있기에 emailSender에는 only을 적용할 수 있다.
728x90
반응형
'Spring' 카테고리의 다른 글
엑셀 다운로드시 암호화를 하고 싶다면? (0) | 2023.08.07 |
---|---|
AWS SQS와 EventBridge를 활용한 스케줄러 만들기 (0) | 2023.06.27 |
스프링 JPA 환경 변수 중 몰랐던 것들 (0) | 2022.11.01 |
카프카 컨슈머 그룹을 추가한 시점 이후의 메시지만 받기 (0) | 2022.10.07 |
테스트할 때 필요한 객체를 일일이 만들기 귀찮을 때 (0) | 2022.09.29 |
Comment