【问题标题】:Testing email services in SpringBoot在 Spring Boot 中测试电子邮件服务
【发布时间】:2017-08-01 15:12:16
【问题描述】:

我使用 Spring Initializer、嵌入式 Tomcat、Thymeleaf 模板引擎生成了一个 Spring Boot Web 应用程序,并将其打包为可执行 JAR 文件。

使用的技术:

Spring Boot 1.4.2.RELEASE、Spring 4.3.4.RELEASE、Thymeleaf 2.1.5.RELEASE、Tomcat 嵌入 8.5.6、Maven 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());
        }
    }
}

我已经创建了这个测试类

@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)}

【问题讨论】:

  • 为 MailClient 和具有 main() 方法的类提供包结构,我们通过该方法运行启动应用程序。
  • 作为旁注。只要有可能,就不要重新发明轮子。看看 Spring Boot Email Tools library

标签: spring spring-mvc spring-boot smtp junit4


【解决方案1】:

问题是您想在不提供 bean 的情况下运行集成测试! 无论何时使用@Autowired,您都需要通过上下文提供自动装配组件馈送所需的bean。 因此,您需要在该测试类中添加一个带有@Configuration 注释的静态类。此外,测试类还需要通过@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。 我认为值得使用该库,并可能为存储库提供新功能,而不是花时间用模板引擎重新实现电子邮件支持。

【讨论】:

    猜你喜欢
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 2011-06-06
    • 1970-01-01
    • 2018-01-08
    相关资源
    最近更新 更多