경험/이슈

[JUnit5] 통합 테스트 환경에서의 예상치 못한 이슈: @MockBean과 @Autowired의 병행 사용

2024. 1. 9.
목차
  1. 문제 상황
  2. 문제해결
728x90

우선 우리의 테스트 환경 구성은 두 가지 핵심 추상 클래스, ControllerTestSupport와 IntegrationTestSupport에 의존한다. 이 두 클래스를 통해 통합 테스트 환경을 구축했다. 중요한 점은, 이 구조를 통해 스프링 부트 인스턴스를 단 두 개만 로드하도록 설정했다는 것이다. 이렇게 함으로써, 테스트 환경의 효율성과 관리의 용이성을 동시에 달성할 수 있었다.

 

문제 상황

문제상황 인지: 평소와 같이 테스트를 돌려보고 테스트가 조금 느려진 것 같아서 확인해 보니 스프링 부트가 3개가 올라가 있었고, 테스트 코드를 확인해 봤다.

@ActiveProfiles("test")
@SpringBootTest
public class ConfirmEmailServiceTest {

    @Autowired
    private ConfirmEmailService confirmEmailService;

    @Autowired
    private ConfirmEmailRepository confirmEmailRepository;

    @Autowired
    private ConfirmEmailReadService confirmEmailReadService;

    @Autowired
    private SecurityService securityService;

    @AfterEach
    void tearDown() {
        confirmEmailRepository.deleteAllInBatch();
    }
	
    // ...
	
}
// 수정
public class ConfirmEmailServiceTest extends IntegrationTestSupport {
	
    @Autowired
    private ConfirmEmailService confirmEmailService;

    @Autowired
    private ConfirmEmailRepository confirmEmailRepository;

    @Autowired
    private ConfirmEmailReadService confirmEmailReadService;

    @Autowired
    private SecurityService securityService;

    @AfterEach
    void tearDown() {
        confirmEmailRepository.deleteAllInBatch();
    }
    
    // ...
    
}

문제상황 분석: 조금 이상했던 점은 분명 테스트 환경을 통합하기로 했는데 이렇게 한 이유가 있었을 것이라고 생각하고 수정한 뒤 테스트를 돌려봤는데, 아래 함수에서 테스트가 실패했다.

@DisplayName("이메일 인증을 처리한다.")
@Test
void confirmEmail(){
    ConfirmEmail confirmEmail = createConfirmEmail("test@test.com", "testtesttest", ConfirmStatus.INCOMPLETE);
    ConfirmEmail savedConfirmEmail =  confirmEmailRepository.save(confirmEmail);

    confirmEmailService.confirmEmail(securityService.encrypt(savedConfirmEmail.getEmail()+"/"+savedConfirmEmail.getAuthKey()));

    ConfirmEmail findConfirmEmail = confirmEmailReadService.findByEmailAndAuthKey(savedConfirmEmail.getEmail(), savedConfirmEmail.getAuthKey());

    assertThat(findConfirmEmail.getConfirmStatus()).isEqualTo(ConfirmStatus.COMPLETE);
}

문제상황: 테스트가 실패한 이유는 바로 `SecurityService` 때문이었는데 `IntergrationTestSupport`에 `@MockBean`으로 되어있어서 그랬던 것이다!

@ActiveProfiles("test")
@SpringBootTest
public abstract class IntegrationTestSupport {

    @MockBean
    protected SecurityService securityService;

    @MockBean
    protected MailService mailService;
}

 

문제해결

`BDDMockito.given`을 사용해서 해결했다. (+ given, when, then 구조를 사용 안 하셔서 추가했다.)

@DisplayName("이메일 인증을 처리한다.")
@Test
void confirmEmail() {
    // given
    ConfirmEmail confirmEmail = createConfirmEmail("test@test.com", "testtesttest", ConfirmStatus.INCOMPLETE);

    ConfirmEmail savedConfirmEmail = confirmEmailRepository.save(confirmEmail);

    String inputForEncryption = savedConfirmEmail.getEmail() + "/" + savedConfirmEmail.getAuthKey();
    String expectedEncryptedOutput = "encryptedString";

    given(securityService.encrypt(inputForEncryption)).willReturn(expectedEncryptedOutput);
    given(securityService.decrypt(expectedEncryptedOutput)).willReturn(inputForEncryption);

    // when
    confirmEmailService.confirmEmail(securityService.encrypt(inputForEncryption));

    // then
    ConfirmEmail findConfirmEmail = confirmEmailReadService.findByEmailAndAuthKey(savedConfirmEmail.getEmail(), savedConfirmEmail.getAuthKey());
    assertThat(findConfirmEmail.getConfirmStatus()).isEqualTo(ConfirmStatus.COMPLETE);
}
더보기

`SecurityService`의 `encrypt()`와 `decrypt()` 각각의 테스트가 존재할 것이라고 생각하고 Mocking을 한 건데 없어서 그것도 추가해야 할 것 같다..ㅠㅠ (코드리뷰 꼼꼼히..)

약 6 sec > 4.9 sec 약 1초(18.33%) 정도 개선했다.

 

 

 

언제나 잘못된 설명이나 부족한 부분에 대한 피드백은 환영입니다🤍

728x90
저작자표시 비영리 변경금지 (새창열림)
  1. 문제 상황
  2. 문제해결
'경험/이슈' 카테고리의 다른 글
  • [Scheduler] [AWS Lambda] 배치 시스템 구성
  • [APM] Pinpoint 구성 중 이슈 정리
  • Github Actions로 PR 테스트 자동화를 진행하면서 했던 삽질
  • MongoDB ➜ S3 백업 자동화 이슈 (용량 부족으로 인한 다운)
호야_
호야_
안녕하세요😊 아는 것만 보이는 게 아닌, 아는 만큼 보인다고 생각하는 백엔드 개발자입니다.
호야_
개발잠
호야_
전체
오늘
어제
  • 분류 전체보기 (28)
    • 경험 (28)
      • 이슈 (12)
      • 기술 (11)
      • 회고 (5)

블로그 메뉴

  • 깃허브
  • 블로그관리 홈
  • 글쓰기

인기 글

최근 글

최근 댓글

250x250
hELLO · Designed By 정상우.
호야_
[JUnit5] 통합 테스트 환경에서의 예상치 못한 이슈: @MockBean과 @Autowired의 병행 사용
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.