[사용 스택]
- Spring Boot 3.x
- Java 17
- Junit 5
- mockito
개발이 끝난 기존의 프로젝트에 테스트를 추가하고 있는 도중에 이 문제를 찾게 되었습니다.
특정 서비스의 메서드들이 하나의 중복된 로직을 수행하고 있었고
그 로직을 같은 클래스 내부에 메서드로 추출해서 사용하고 있습니다.
모든 메서드에서 그 로직을 테스트하는 것은 효율적이지 않으며 불필요하다는 판단을 했습니다.
해결방안
1. 해당 메서드를 외부 클래스로 추출하기
일단 역할에 맞게 해당 메서드를 새로운 클래스로 추출하는 방법이 가장 와닿았습니다.
이렇게 하면 각 역할에 맞는 클래스로 올바르게 사용될 수 있다고 생각했습니다.
또한, Mocking을 통해 테스트를 독립적으로 수행할 수 있습니다.
하지만, 이렇게 하려면 기존의 코드를 수정해야만 합니다.
2. 서비스를 스파이 객체로 테스트하기
이 방법은 지금 현재의 비즈니스 코드를 수정하지 않고 테스트를 가능하도록 하는 방법입니다.
테스트하고자 하는 서비스를 @Spy 어노테이션으로 설정하고
해당 메서드의 테스트를 분리할 수 있게 됩니다.
//...
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class ServiceImplTest {
@Spy
@InjectMocks
ServiceImpl Service;
@Mock
Repository repository;
@Test
public void methodA() throws Exception {
// given
when(repository.findById(anyLong())
.thenReturn(Optional.of(mock(Entity.class)));
// 중복되어 사용되는 메서드를 Mocking
doReturn(mock(ResDTO.class))
.when(service).duplicatedMethod();
// when
service.methodA();
// then
// 해당 메서드가 정상 실행되었는지 확인
verify(service, times(1)).duplicatedMethod();
}
// 중복 메서드를 독립적으로 테스트
@Test
public void duplicatedMethod() throws Exception {
// given
// when
ResDTO response = service.duplicatedMethod();
// then
assertThat(response).isNotNull();
}
결론
기존 코드를 수정하지 않고 테스트를 완성하기 위해서
지금은 스파이 객체를 사용해 테스트를 진행하기로 결정했습니다.
물론 더 깔끔하게 관리하는 것은 외부 클래스로 추출하는 것이므로
현재 주어진 과제를 마무리하고 해당 부분의 리팩터링을 하고자 합니다.
외부 클래스로 추출된다면 Spy 객체를 사용하는 것이 아니라
새로운 클래스를 @Mock 어노테이션을 통해 Mock 객체로 사용하면 됩니다.
Reference
https://yangtaeyoung.github.io/blog/spring/same-class-method-test/
https://effortguy.tistory.com/144
'WEB > Spring' 카테고리의 다른 글
단위 테스트 - Service (feat. 테스트 더블) (0) | 2024.08.28 |
---|---|
단위 테스트 - Repository (feat. 테스트 픽스쳐) (0) | 2024.08.27 |
RestControllerAdvice로 전역에서 발생된 예외 처리하기. (0) | 2024.05.01 |
Spring Security 프레임워크로 로그인에 성공하면 JWT 발급하기 (0) | 2024.04.17 |
Spring Security 프레임워크로 OAuth2 로그인 (0) | 2024.04.05 |