JUnit5와 GreenMail을 사용하여 이메일이 정상적으로 수신되는지 테스트 하는법을 소개한다.
Spring에서 SMTP를 사용하여 이메일을 보내는 기능은 주제에 벗어나므로 간단하게 소개한다.
자세한 내용이 궁금하면 검색을 이용하기를 바란다.
JavaMailsender를 이용하여 Gmail을 통해 이메일을 발송하도록 구현하였다.
@Configuration
class SmtpEmailConfig {
@Value("\${spring.mail.transport.protocol}")
lateinit var protocol: String
@Value("\${spring.mail.properties.mail.smtp.auth}")
private var auth : Boolean = false
@Value("\${spring.mail.properties.mail.smtp.starttls.enable}")
private var starttls : Boolean = false
@Value("\${spring.mail.debug}")
private var debug : Boolean = false
@Value("\${spring.mail.host}")
private lateinit var host: String
@Value("\${spring.mail.port}")
private var port : Int = 0
@Value("\${spring.mail.username}")
private lateinit var username: String
@Value("\${spring.mail.password}")
private lateinit var password: String
@Value("\${spring.mail.default-encoding}")
private lateinit var encoding: String
@Bean
fun javaMailSender() : JavaMailSender {
val sender = JavaMailSenderImpl()
val properties = Properties()
properties["mail.transport.protocol"] = protocol
properties["mail.smtp.auth"] = auth
properties["mail.smtp.starttls.enable"] = starttls
properties["mail.smtp.debug"] = debug
sender.host = host
sender.username = username
sender.password = password
sender.port = port
sender.javaMailProperties = properties
sender.defaultEncoding = encoding
return sender
}
}
@Component
class SmtpMailSender(private val sender : JavaMailSender) : MailSender {
override fun send(to: String, subject: String, content: String) {
val message = SimpleMailMessage()
with(message) {
setTo(to)
setSubject(subject)
setText(content)
}
sender.send(message)
}
}
GreenMail을 사용하기 위한 의존성을 추가한다.
testImplementation("com.icegreen:greenmail-junit5:1.6.0")
우리는 이메일 발송만을 테스트할 예정이기 때문에 SMTP만 사용하도록 하였고 Junit5의 확장 기능중 @RegisterExtension
을 활용하여 메일 서버를 실행하여 테스트할 수 있도록 하였다.
@JvmField
@RegisterExtension
static GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTP)
.withConfiguration(GreenMailConfiguration.aConfig().withUser("seok2", "1q2w3e!!"))
.withPerMethodLifecycle(false);
이 코드를 통하여 GreenMail이 샌드박스 환경에서 실행되어 독립적인 테스트가 가능하도록 한다.
withPerMethodLifecycle 옵션을 통하여 재사용 여부를 결정하는데 사용되며 테스트를 독립적으로 구성하는데 활용할 수 있다.
이제 SmtpEmailConfig에 TestProperty 값을 넣어주면 샌드박스로 이메일을 수신할 수 있다.
깃헙액션을 사용하여 자동화된 테스트를 할 경우 설정값의 이메일정보의 노출을 막기위한 추가 작업이 필요하지만 GreenMail을 사용하면서 그런 번거로움도 사라졌다.
spring:
mail:
host: 127.0.0.1
port: 3025
username: seok2
password: welcome
properties:
mail:
smtp:
auth: true
starttls:
enable: true
transport:
protocol: smtp
debug: true
default-encoding: UTF-8
테스트 전체 코드는 아래와 같다.
@TestPropertySource(locations = ["/application.yml"])
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
internal class SmtpMailSenderTest(
@Autowired
private val sender: MailSender
) {
companion object {
@JvmField
@RegisterExtension
val smtp: GreenMailExtension = GreenMailExtension(ServerSetupTest.SMTP)
.withConfiguration(GreenMailConfiguration.aConfig().withUser("seok2", "welcome"))
.withPerMethodLifecycle(false)
}
@Test
fun `이메일 발송 테스트`() {
val content = "Have a good day"
val to = "seok2@spring.io"
sender.send(to, "Hello Green Mail", content)
smtp.waitForIncomingEmail(1) // 비동기로 동작하기 떄문에 대기하도록 하였다.
val received = smtp.receivedMessages[0]
assertThat(GreenMailUtil.getBody(received)).isEqualTo(content)
assertThat(received.allRecipients[0].toString()).isEqualTo(to)
}
}
위 예제의 사용한 소스 코드는 GitHub에서 확인할 수 있습니다.