Loading...

프로젝트/레시피마켓 / / 2022. 6. 20. 15:24

Mockito 환경에서 JavaMailSender 테스트 방법

반응형

UserService 단위 테스트

 

임시 패스워드 발급 테스트 진행 중 이메일이 실제로 전송이 되는지 테스트를 해야하는데

실제 객체는 Mock로 띄울 수 없기 때문에 @Spy로 UtilEmail을 실제로 띄웠다.

 

// 실제 UserService 본코드
@Transactional
public User 임시패스워드발급(PasswordResetReqDto passwordResetReqDto) {

    ... 생략
    
    // 3. 임시 비밀번호 이메일로 전송 (받는 사람, 제목, 내용)
    utilEmail.sendEmail(userEntity.getEmail(), "임시 비밀번호 발급", "임시 비밀번호 : " + tempPw);

}

 

utilEmail.sendEmail( )을 테스트해볼건데 생성자로 JavaMailSender를 주입해줘야한다.

 

package site.metacoding.recipemarket.util;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Component
public class UtilEmail {

    private final JavaMailSender sender;

    public void sendEmail(String toAddress, String subject, String body) {

        MimeMessage message = sender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message);

        try {
            helper.setTo(toAddress);
            helper.setSubject(subject);
            helper.setText(body);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        sender.send(message);
    }
}

 

그러면 또 JavaMailSender를 @Spy로 띄워서 주입해줘야하는데 JavaMailSender는 인터페이스이기 때문에 띄우질 못한다.

 

테스트 환경에서만 사용할 메일 객체를 만들기 위해 JavaMailSenderImpl을 구현해보자.

 

 


 

1. 테스트 파일에서 사용할 프로파일(application-test.yml) 지정 

@ActiveProfiles("test") // 프로파일 설정
@ExtendWith(MockitoExtension.class) 
public class UserServiceTest {

}

 

2. 프로파일에 메일 객체 생성 코드 지우기

spring:
  # mail:
  #   host: smtp.gmail.com # smtp 프로토콜
  #   port: 587
  #   username: 아이디
  #   password: 비밀번호
  #   properties:
  #     mail:
  #       smtp:
  #         starttls:
  #           enable: true
  #           required: true
  #         auth: true

 

3. JavaMailSenderImpl 구현체 만들기

이 파일에서 메일 관련 설정들을 직접 해준다.

package site.metacoding.recipemarket.config;

import java.util.Properties;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

@Configuration
public class MailConfig {

    @Bean
    public JavaMailSender getMailSender() {

        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

        mailSender.setHost("smtp.gmail.com");
        mailSender.setPort(587);
        mailSender.setUsername("아이디");
        mailSender.setPassword("앱비밀번호");

        Properties javaMailProperties = new Properties();

        javaMailProperties.put("mail.smtp.starttls.enable", "true");
        javaMailProperties.put("mail.smtp.auth", "true");
        javaMailProperties.put("mail.transport.protocol", "smtp");
        javaMailProperties.put("mail.debug", "true");

        mailSender.setJavaMailProperties(javaMailProperties);

        return mailSender;
    }
}

 

4. 구글 앱 비밀번호 설정

 

22년 5월 30일부터 보안 수준이 낮은 앱 허용 기능 서비스가 종료되었기 때문에 앱 비밀번호 설정을 해줘야한다.

 

https://blog.naver.com/gih1214/222761678933

 

[Spring] javax.mail.authenticationfailedexception 해결하기

비밀번호 찾기 - 임시 비밀번호를 발급해서 해당 메일로 발송하는 기능을 구현하는데 500번 오류가 발생했...

blog.naver.com

 

5. 의존성 주입하기

package site.metacoding.recipemarket.service;

import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.context.ActiveProfiles;

import site.metacoding.recipemarket.config.MailConfig;
import site.metacoding.recipemarket.util.UtilEmail;

@ActiveProfiles("test")
@ExtendWith(MockitoExtension.class) // Mockito 컨테이너 생성, IoC 컨테이너 내부에 있는 것처럼 속이기
public class UserServiceTest {

        @Spy
        private MailConfig mailConfig = new MailConfig();

        @Spy
        private UtilEmail utilEmail = new UtilEmail(mailConfig.getMailSender());
}

 

6. 실제 테스트하기

실제 서비스를 호출해보면 테스트가 문제 없이 잘 통과할 것이다!!

@Test
public void 임시패스워드발급_테스트() {

...생략

        // when
        User userEntity = userService.임시패스워드발급(dto);
}
반응형