프로젝트 기록/TestCode

[Test] Void를 반환하는 테스트는 어떤 방식으로 검증할까?

코딩 코딩 코오딩 2024. 1. 28. 13:54

문제

  • 테스트 코드를 작성하는 도중 void를 리턴하는 방식의 코드를 작성하게 되었다.
  • Mock 을 사용하지 않는 순수 자바 코드만을 이용한 테스트를 작성하는 것을 유지했기 때문에 고민을 하게 되었다.

해결 방법

  1. AssertThatCode 을 이용하는 방법
  2. assertThatCode(()->certificationService.send(email, 1,testUuidHolder.random())) .doesNotThrowAnyException();
  • assertThatCode 는 정상적 동작을 검증하는 코드에 많이 사용된다.
  • 테스트 하고자 하는 메서드를 실행하고 예외가 발생하지 않으면 되는것 이다.
    하지만, 이러한 작성은 문제가 될 수 있다 생각했다. 단순히 커버리지를 높이는 테스트에 불과하기 때문이다. 내가 실행하고자 하는 것은 제대로 된 검증 메일이 발송 되었는지 가 궁금했던 것이다.

이러한 행위가 궁금했고 다른 방법을 생각해보게 되었다.

  1. 호출한 메서드안에 있는 메서드들이 잘 실행 되었는지 확인
  • 내가 테스트 해보고 싶은 것은 메일이 발송되는 행위를 제대로 전달했는 지 궁금한 것이다.
  • 이미 테스트를 위한 가짜 객체를 만들어 두게 되면서 실행 되었는지 확인하는 fakeMailSenderIsExecute 필드를 만들어 두고 확인하게 되었다.
  • CertificationService send 메서드 내에 있는 mailSender.send 의 행위 실행이 궁금한 것이다.
public class CertificationService {

    private final MailSender mailSender;

    public void send(String email, long userId, String certificationCode) {
        String certificationUrl = generateCertificationUrl(userId, certificationCode);
        String title = "Please certify your email address";
        String content = "Please click the following link to certify your email address: " + certificationUrl;
        mailSender.send(email, title, content);
    }
}
public class FakeMailSender implements MailSender {
    public String email;
    public String title;
    public String content;
    public boolean fakeMailSenderIsExecute;
    @Override
    public void send(String email, String title, String content) {
        this.email = email;
        this.title = title;
        this.content = content;
        this.fakeMailSenderIsExecute = true;
    }
}
@Test  
@DisplayName("인증 메일 발송 테스트 메일이 발송 되었을까?")  
void mailSendTest() {  
    //Given  

    FakeMailSender fakeMailSender = new FakeMailSender();  
    CertificationService certificationService = new  CertificationService(fakeMailSender);  
    TestUuidHolder testUuidHolder = new TestUuidHolder("test");  
    String email = "test@gmail.com";  
    //When  
    //Then    
    assertThatCode(()->certificationService.send(email, 1,testUuidHolder.random()))  
            .doesNotThrowAnyException();  
    assertThat(fakeMailSender.fakeMailSenderIsExecute).isEqualTo(true);  
}
  • 결론
    • 대부분 Mock 객체를 만들어 테스트 하는 코드가 많이 있지만, 나는 최대한 외부 라이브러리를 사용하지 않는 테스트 코드를 만들어 빠르게 작동하고 확인할 수 있는 테스트 코드 작성을 목표로 했기 때문에 이런 방식을 사용하게 되었다.

참고
AssertThatCode
https://velog.io/@rg970604/AssertThatThrownBy%EC%99%80-AssertThatCode%EC%9D%98-%EC%B0%A8%EC%9D%B4

반응형