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