전주호
WebSurf
전주호
전체 방문자
오늘
어제
  • 분류 전체보기 (63)
    • CS (1)
    • 프로그래밍 언어 (3)
      • JAVA (1)
      • Python (2)
    • WEB (35)
      • Spring (21)
      • FastAPI (1)
      • React (4)
    • Git (1)
    • Database (2)
    • Cloud (4)
    • Docker (0)
    • Linux (0)
    • AI (8)
      • ComputerVision (3)
      • CUDA (1)
      • Anaconda (1)
      • NLP (1)
    • ETC (9)
    • Project (0)
      • GolaBlur (0)
    • 알고리즘 문제 풀이 (0)
      • 프로그래머스 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • react
  • Internet
  • db
  • EC2
  • 백엔드
  • springboot
  • AI
  • 클라우드
  • spring
  • web
  • MobileFaceSwap
  • 백엔드로드맵
  • http
  • jwt
  • jpa
  • API
  • 테스트
  • websocket
  • junit
  • 트러블슈팅
  • conda
  • cloud
  • oauth2
  • 스프링
  • 단위테스트
  • AWS
  • 문제해결
  • Spring Security
  • S3
  • PYTHON

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
전주호

WebSurf

WEB/Spring

Service의 메서드들이 중복해서 사용하는 로직을 테스트하기

2024. 8. 20. 17:13
반응형

[사용 스택]

- 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/

 

(JAVA) Spring에서 같은 서비스 내의 메소드 Mocking 하기

일반적으로 Spring은 Layered Architecture 를 따르고 있으며, 서비스에서 주로 비즈니스 로직을 처리하게 된다. 서비스의 코드가 많아지면 많아질 수록 비슷한 코드가 많아지게 되는데, 이런 경우 공통

yangtaeyoung.github.io

https://effortguy.tistory.com/144

 

[Java] Mockito 사용법 (4) - 검증 (Verify)

이번 포스팅에선 Mockito를 이용해 스터빙한 메소드가 제대로 실행이 됐는지 확인해보는 메소드에 대해서 알아보겠습니다. 스터빙한 메소드를 검증하는 방법 verify 메소드를 이용해서 스터빙한

effortguy.tistory.com

 

반응형
저작자표시 (새창열림)

'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
    'WEB/Spring' 카테고리의 다른 글
    • 단위 테스트 - Service (feat. 테스트 더블)
    • 단위 테스트 - Repository (feat. 테스트 픽스쳐)
    • RestControllerAdvice로 전역에서 발생된 예외 처리하기.
    • Spring Security 프레임워크로 로그인에 성공하면 JWT 발급하기
    전주호
    전주호

    티스토리툴바