【问题标题】:How do I unit test a my class which sends emails?如何对发送电子邮件的班级进行单元测试?
【发布时间】:2020-03-11 22:49:07
【问题描述】:

我有这样的课:

public class StarshipEmailSender {

    @Value("${email.from-email-address:}")
    String from;

    @Value("${email.from-name:}")
    private String fromName;

    @Value("${email.smtp.credentials-path:}")
    String credentialPath;

    @Value("${email.smtp.host:}")
    String smtpHost;

    @Value("${email.smtp.port:587}")
    private int smtpPort;

    @Autowired
    private AClientFactory clientFactory;

    private Properties sessionProperties;
    private String smtpUsername = null;
    private String smtpPassword = null;

    public StarshipEmailSender() {
        sessionProperties = new Properties();
        sessionProperties.put("mail.transport.protocol", "smtp");
        sessionProperties.put("mail.smtp.port", smtpPort);
        sessionProperties.put("mail.smtp.starttls.enable", "true");
        sessionProperties.put("mail.smtp.auth", "true");
    }


    public void sendMail(List<String> to, String subject, String contentType, String body)
            throws MessagingException, UnsupportedEncodingException {

        Session session = Session.getDefaultInstance(sessionProperties);
        MimeMessage msg = contructMIMEMessage(session, to, subject, contentType, body);
        Transport transport = session.getTransport();
        try {
            long start = System.currentTimeMillis();

            transport.connect(smtpHost, smtpPort, smtpUsername, smtpPassword);
            transport.sendMessage(msg, msg.getAllRecipients());
            log.info("Email sent to : " + to + " in " + (System.currentTimeMillis()-start) + " millis");
        } finally {
            transport.close();
        }
    }


    MimeMessage contructMIMEMessage(Session session, List<String> to, String subject, String contentType,
            String body) throws UnsupportedEncodingException, MessagingException {
        // code to construct a mime message ...
    }


}

如何对sendMail() 方法进行单元测试?它有很多在方法中声明的变量,我无法从测试类中模拟它们:/我已经模拟了所有其他方法,因为它们更容易,但这种方法让我感到困惑。还是我以一种不允许单元测试灵活性的糟糕方式构建了这个类?

【问题讨论】:

    标签: java unit-testing mocking mockito


    【解决方案1】:

    该服务目前不可进行单元测试。我会推荐:

    • 使用 @ConfigurationProperties 将 Spring 属性提取到单独的类中。
    • 自动装配您所依赖的所有类,而不是在方法本身中获取它们的实例。 (上面提到的配置,SessionTransport 等 - Spring 也应该有一个built-in support for sending emails,所以也许你可以让你的生活更轻松。)
    • 使用构造函数注入而不是字段注入。

    之后,您应该能够使用所有必要的依赖项(真实的或模拟的)构建您的 StarshipEmailSender 并测试行为。

    【讨论】:

      猜你喜欢
      • 2011-07-12
      • 2011-09-16
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      • 2014-11-04
      • 2011-03-07
      • 2011-01-02
      • 1970-01-01
      相关资源
      最近更新 更多