在 Spring Boot 中测试电子邮件服务
Testing email services in SpringBoot
我使用 Spring 初始化程序生成了 Spring 启动 Web 应用程序,嵌入 Tomcat,Thymeleaf 模板引擎,并打包为可执行 JAR 文件。
使用的技术:
Spring 引导 1.4.2.RELEASE、Spring 4.3.4.RELEASE、Thymeleaf 2.1.5.RELEASE、Tomcat 嵌入 8.5.6 , 行家 3, Java 8
我想测试这个电子邮件服务
@Service
public class MailClient {
protected static final Logger looger = LoggerFactory.getLogger(MailClient.class);
@Autowired
private JavaMailSender mailSender;
private MailContentBuilder mailContentBuilder;
@Autowired
public MailClient(JavaMailSender mailSender, MailContentBuilder mailContentBuilder) {
this.mailSender = mailSender;
this.mailContentBuilder = mailContentBuilder;
}
//TODO: in a properties
public void prepareAndSend(String recipient, String message) {
MimeMessagePreparator messagePreparator = mimeMessage -> {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setFrom("nunito@calzada.com");
messageHelper.setTo(recipient);
messageHelper.setSubject("Sample mail subject");
String content = mailContentBuilder.build(message);
messageHelper.setText(content, true);
};
try {
if (looger.isDebugEnabled()) {
looger.debug("sending email to " + recipient);
}
mailSender.send(messagePreparator);
} catch (MailException e) {
looger.error(e.getMessage());
}
}
}
我创建了这个测试class
@RunWith(SpringRunner.class)
public class MailClientTest {
@Autowired
private MailClient mailClient;
private GreenMail smtpServer;
@Before
public void setUp() throws Exception {
smtpServer = new GreenMail(new ServerSetup(25, null, "smtp"));
smtpServer.start();
}
@Test
public void shouldSendMail() throws Exception {
//given
String recipient = "nunito.calzada@gmail.com";
String message = "Test message content";
//when
mailClient.prepareAndSend(recipient, message);
//then
String content = "<span>" + message + "</span>";
assertReceivedMessageContains(content);
}
private void assertReceivedMessageContains(String expected) throws IOException, MessagingException {
MimeMessage[] receivedMessages = smtpServer.getReceivedMessages();
assertEquals(1, receivedMessages.length);
String content = (String) receivedMessages[0].getContent();
System.out.println(content);
assertTrue(content.contains(expected));
}
@After
public void tearDown() throws Exception {
smtpServer.stop();
}
}
但是我在 运行 测试
时遇到了这个错误
Error creating bean with name 'com.tdk.service.MailClientTest': Unsatisfied dependency expressed through field 'mailClient'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.tdk.service.MailClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
问题是您想 运行 在不提供 bean 的情况下进行集成测试!
无论何时使用 @Autowired
,您都需要通过上下文提供自动装配组件提要所需的 bean。
因此,您需要在带有 @Configuration
注释的测试 class 中添加静态 class。此外,测试 class 还需要通过 @ContextConfiguration
注释知道必须使用哪个配置。此处示例:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {MailClientTest.ContextConfiguration.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MailClientTest {
@Configuration
@TestPropertySource(locations = "classpath:application.properties",
properties ={"my.additiona.property=123"})
@ComponentScan(basePackages = {"com.tdk.service"})
public static class ContextConfiguration {
@Bean
public JavaMailSender mailSender{
return ... //create the instance here
}
@Bean
public MailContentBuilder mailContentBuilder() {
return ... //create the instance here
}
}
}
无论如何,正如我已经在评论中指出的那样,不要浪费时间重新发明轮子。那里已经有一个图书馆可以为您完成所有这些工作。我说的是 Spring Boot Email Tools。
我认为值得使用该库并可能为存储库贡献新功能,而不是花时间使用模板引擎重新实现电子邮件支持。
我使用 Spring 初始化程序生成了 Spring 启动 Web 应用程序,嵌入 Tomcat,Thymeleaf 模板引擎,并打包为可执行 JAR 文件。
使用的技术:
Spring 引导 1.4.2.RELEASE、Spring 4.3.4.RELEASE、Thymeleaf 2.1.5.RELEASE、Tomcat 嵌入 8.5.6 , 行家 3, Java 8
我想测试这个电子邮件服务
@Service
public class MailClient {
protected static final Logger looger = LoggerFactory.getLogger(MailClient.class);
@Autowired
private JavaMailSender mailSender;
private MailContentBuilder mailContentBuilder;
@Autowired
public MailClient(JavaMailSender mailSender, MailContentBuilder mailContentBuilder) {
this.mailSender = mailSender;
this.mailContentBuilder = mailContentBuilder;
}
//TODO: in a properties
public void prepareAndSend(String recipient, String message) {
MimeMessagePreparator messagePreparator = mimeMessage -> {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setFrom("nunito@calzada.com");
messageHelper.setTo(recipient);
messageHelper.setSubject("Sample mail subject");
String content = mailContentBuilder.build(message);
messageHelper.setText(content, true);
};
try {
if (looger.isDebugEnabled()) {
looger.debug("sending email to " + recipient);
}
mailSender.send(messagePreparator);
} catch (MailException e) {
looger.error(e.getMessage());
}
}
}
我创建了这个测试class
@RunWith(SpringRunner.class)
public class MailClientTest {
@Autowired
private MailClient mailClient;
private GreenMail smtpServer;
@Before
public void setUp() throws Exception {
smtpServer = new GreenMail(new ServerSetup(25, null, "smtp"));
smtpServer.start();
}
@Test
public void shouldSendMail() throws Exception {
//given
String recipient = "nunito.calzada@gmail.com";
String message = "Test message content";
//when
mailClient.prepareAndSend(recipient, message);
//then
String content = "<span>" + message + "</span>";
assertReceivedMessageContains(content);
}
private void assertReceivedMessageContains(String expected) throws IOException, MessagingException {
MimeMessage[] receivedMessages = smtpServer.getReceivedMessages();
assertEquals(1, receivedMessages.length);
String content = (String) receivedMessages[0].getContent();
System.out.println(content);
assertTrue(content.contains(expected));
}
@After
public void tearDown() throws Exception {
smtpServer.stop();
}
}
但是我在 运行 测试
时遇到了这个错误Error creating bean with name 'com.tdk.service.MailClientTest': Unsatisfied dependency expressed through field 'mailClient'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.tdk.service.MailClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
问题是您想 运行 在不提供 bean 的情况下进行集成测试!
无论何时使用 @Autowired
,您都需要通过上下文提供自动装配组件提要所需的 bean。
因此,您需要在带有 @Configuration
注释的测试 class 中添加静态 class。此外,测试 class 还需要通过 @ContextConfiguration
注释知道必须使用哪个配置。此处示例:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {MailClientTest.ContextConfiguration.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MailClientTest {
@Configuration
@TestPropertySource(locations = "classpath:application.properties",
properties ={"my.additiona.property=123"})
@ComponentScan(basePackages = {"com.tdk.service"})
public static class ContextConfiguration {
@Bean
public JavaMailSender mailSender{
return ... //create the instance here
}
@Bean
public MailContentBuilder mailContentBuilder() {
return ... //create the instance here
}
}
}
无论如何,正如我已经在评论中指出的那样,不要浪费时间重新发明轮子。那里已经有一个图书馆可以为您完成所有这些工作。我说的是 Spring Boot Email Tools。 我认为值得使用该库并可能为存储库贡献新功能,而不是花时间使用模板引擎重新实现电子邮件支持。