Spring Boot邮件测试问题:如何从message.properties读取邮件主题与内容
Spring Boot 邮件发送测试用例:从message.properties读取内容的正确姿势
问题根源
你直接把属性键字符串"event.appointment.slot.user.repeat"赋值给邮件主题,Spring不会自动解析成对应的属性值;而错误使用$[0].code语法,这不是Spring读取属性的正确方式。
解决方案步骤
1. 确保MessageSource配置正确
Spring Boot默认会自动加载src/main/resources下的message.properties,如果需要自定义位置或编码,可在application.properties中配置:
spring.messages.basename=messages spring.messages.encoding=UTF-8
2. 在邮件发送类中注入并使用MessageSource
通过构造器注入MessageSource,调用其getMessage()方法读取属性值,支持动态参数替换:
import org.springframework.context.MessageSource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Component; @Component public class EmailService { private final JavaMailSender emailSender; private final MessageSource messageSource; public EmailService(JavaMailSender emailSender, MessageSource messageSource) { this.emailSender = emailSender; this.messageSource = messageSource; } public void sendCancellationEmail(Doctor doctor, EventData eventData) { SimpleMailMessage message1 = new SimpleMailMessage(); message1.setFrom("develop@gmail.com"); message1.setTo(doctor.getEmail()); // 读取主题属性值,无参数时传null String subject = messageSource.getMessage("event.appointment.cancelled", null, null); message1.setSubject(subject); // 先在message.properties中定义带占位符的文本: // event.appointment.cancelled.text=You have one {0} appointment at {1} to {2} was cancelled by patient. String text = messageSource.getMessage("event.appointment.cancelled.text", new Object[]{eventData.getTitle(), eventData.getStart(), eventData.getEnd()}, null); message1.setText(text); emailSender.send(message1); } }
3. 编写测试用例
方式1:完整上下文集成测试
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.test.context.TestPropertySource; import static org.mockito.Mockito.*; @SpringBootTest // 配置测试用邮件服务器,避免真实发送邮件 @TestPropertySource(properties = { "spring.mail.host=localhost", "spring.mail.port=1025", "spring.mail.username=test", "spring.mail.password=test" }) public class EmailServiceTest { @Autowired private EmailService emailService; @Autowired private JavaMailSender emailSender; @Test public void testSendCancellationEmail() { // 构造测试数据 Doctor doctor = new Doctor(); doctor.setEmail("doctor@test.com"); EventData eventData = new EventData(); eventData.setTitle("General Checkup"); eventData.setStart("2024-05-20 10:00"); eventData.setEnd("2024-05-20 11:00"); // 执行发送逻辑 emailService.sendCancellationEmail(doctor, eventData); // 验证邮件发送行为 verify(emailSender, times(1)).send(any(SimpleMailMessage.class)); } }
方式2:Mock依赖的单元测试
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.context.MessageSource; import org.springframework.mail.javamail.JavaMailSender; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) public class EmailServiceUnitTest { @Mock private JavaMailSender emailSender; @Mock private MessageSource messageSource; @InjectMocks private EmailService emailService; @Test public void testSendCancellationEmail() { // Mock MessageSource的返回值 when(messageSource.getMessage("event.appointment.cancelled", null, null)) .thenReturn("Appointment Canceled."); when(messageSource.getMessage("event.appointment.cancelled.text", new Object[]{"General Checkup", "2024-05-20 10:00", "2024-05-20 11:00"}, null)) .thenReturn("You have one General Checkup appointment at 2024-05-20 10:00 to 2024-05-20 11:00 was cancelled by patient."); // 构造测试数据 Doctor doctor = new Doctor(); doctor.setEmail("doctor@test.com"); EventData eventData = new EventData(); eventData.setTitle("General Checkup"); eventData.setStart("2024-05-20 10:00"); eventData.setEnd("2024-05-20 11:00"); // 执行发送逻辑 emailService.sendCancellationEmail(doctor, eventData); // 验证邮件发送行为 verify(emailSender, times(1)).send(any(SimpleMailMessage.class)); } }
关键注意点
- 禁止直接将属性键赋值给邮件主题/文本,必须通过
MessageSource.getMessage()获取解析后的值 - 需要动态替换内容时,在
message.properties中用{0}、{1}占位符,调用getMessage时传入对应参数数组 - 测试时可通过Mock工具模拟
MessageSource或JavaMailSender,避免触发真实邮件发送
内容的提问来源于stack exchange,提问作者Preethi
相关产品推荐
相关产品推荐

