org.mockito.exceptions.verification.TooManyActualInvocations
Environment
Language: Java 17
Framework: SpringBoot 3.1.0, Junit5
DB: MySQL, Redis
오류
org.mockito.exceptions.verification.TooManyActualInvocations:
userService bean.create(
refEq(cohttp://m.msgs.domain.user.dto.SignUpRequestDTO@69bf351e)
);
Wanted 1 time:
-> at cohttp://m.msgs.domain.user.service.UserService.create(UserService.java:41)
But was 2 times:
-> at cohttp://m.msgs.domain.user.controller.UserControllerTest.setup(UserControllerTest.java:45)
-> at cohttp://m.msgs.domain.user.controller.UserController.create(UserController.java:30)
UserService의 create 메서드가 너무 많이 호출됨
1번을 의도했으나, 2번이 호출됨
원인
@SpringBootTest
@AutoConfigureMockMvc(addFilters = false)
class UserControllerTest {
@BeforeEach
void setup() {
SignUpRequestDTO signUpDto = SignUpRequestDTO.builder()
.status("M")
.email("temp@email.com")
.phone("01023698745")
.nickname("name")
.password("temp123!")
.confirmPassword("temp123!")
.build();
userService.create(signUpDto);
}
@Test
@DisplayName("Controller: 회원 가입 실패, 중복된 이메일")
void createFailDuplicateEmail() throws Exception {
// given
SignUpRequestDTO signUpDto = SignUpRequestDTO.builder()
.status("M")
.email("temp@email.com")
.phone("01023698745")
.nickname("name")
.password("temp123!")
.confirmPassword("temp123!")
.build();
// when // then
mockMvc.perform(post("/api/v2/users/new")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(signUpDto)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errorMessage").value("이미 존재하는 이메일 입니다."));
// 회원 생성 메소드가 호출되었는지 확인
verify(userService).create(refEq(signUpDto));
}
}
중복 회원 검사를 위해 Test전 @BeforeEach를 사용해서 UserService의 create 메서드를 호출
+ 중복회원 검증 시, UserService의 create 메서드를 호출
→ 총 create 메서드 2회 호출
→ verify 메서드에서 예상 호출 수와 실제 호출 수의 불일치가 발생하여 TooManyActualInvocations 예외 발생
해결
@SpringBootTest
@AutoConfigureMockMvc(addFilters = false)
class UserControllerTest {
@Test
@DisplayName("Controller: 회원 가입 실패, 중복된 이메일")
void createFailDuplicateEmail() throws Exception {
// given
SignUpRequestDTO signUpDto = SignUpRequestDTO.builder()
.status("M")
.email("temp@email.com")
.phone("01023698745")
.nickname("name")
.password("temp123!")
.confirmPassword("temp123!")
.build();
// Mocking 중복된 이메일로 인한 예외 발생
doThrow(new BusinessException(ErrorCode.DUPLICATED_EMAIL))
.when(userService).create(any(SignUpRequestDTO.class));
// when // then
mockMvc.perform(post("/api/v2/users/new")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(signUpDto)))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errorMessage").value("이미 존재하는 이메일 입니다."));
// 회원 생성 메소드가 호출되었는지 확인
verify(userService).create(refEq(signUpDto));
}
}
@BeforeEach를 제거하고 doThrow() 활용
* userService의 create 메서드로 SignUpRequestDTO가 넘겨지면 DUPLICATED_EMAIL Exception 호출로 모킹
📑
참고 자료
'Java > Spring with Error' 카테고리의 다른 글
[해결 방법] "this.bCryptPasswordEncoder" is null (0) | 2024.11.12 |
---|---|
[해결 방법] Failed to determine a suitable driver class (1) | 2024.09.28 |
[해결 방법] Argument(s) are different! (0) | 2024.09.15 |
[해결 방법] NoUniqueBeanDefinitionException (0) | 2024.09.04 |
[해결방법] io.jsonwebtoken.ExpiredJwtException (0) | 2024.08.30 |