首页 > 解决方案 > Junit5 使用 SMTP 使用 GreenMail 服务器测试 Spring 电子邮件

问题描述

我正在尝试为 Spring Email 编写 JUnit5 测试。当我运行测试时,Greenmail 服务器没有收到任何消息。附上相同的代码片段:

@ExtendWith(MockitoExtension.class)
public class EmailServiceImplTest {

Mail emailEntity;

GreenMail serverA;

@InjectMocks
private EmailServiceImpl emailService;

@Mock
private JavaMailSender javaMailSender;

@BeforeEach
void setUp() {
    MockitoAnnotations.initMocks(this);
    emailEntity = mockItemMasterData();
    // Setup fake smtp server.
    serverA = new GreenMail(ServerSetupTest.SMTP);
    serverA.start();
}


private Mail mockItemMasterData() {
    Mail mail = new Mail();
    mail.setFrom("no-reply@test.com");
    mail.setTo("no-reply@test.com");
    mail.setSubject("Spring Mail Integration Testing with JUnit and GreenMail Example");
    mail.setBody("We show how to write Integration Tests using Spring and GreenMail.");
    mail.setSendDate(Date.from(Instant.ofEpochSecond(System.currentTimeMillis())));
    return mail;
}

@Test
public void testSendEmailToAvailableMailboxReturnEmail() throws SendFailedException {

    // Using javamailsenderimpl to send the mail.
    emailService.sendSimpleMessage(emailEntity);

    try {
        Message[] messages = serverA.getReceivedMessages();
        Assert.assertNotNull(messages);
        Assert.assertEquals(1, messages.length);
        Assert.assertEquals(emailEntity.getSubject(), messages[0].getSubject());
        Assert.assertEquals(emailEntity.getBody(), String.valueOf(messages[0].getContent()).contains("body"));

    } catch (MessagingException | IOException e) {
        Assert.fail("Should be able to retrive sent mail.");
    }
}

}

以下是我正在为其编写此测试的课程

@Component
@Slf4j
public class EmailServiceImpl implements EmailService {

@Autowired
private JavaMailSender javaMailSender;

@Override
public void sendSimpleMessage(Mail mail) throws SendFailedException {
    log.info("Send mail started ");
    SimpleMailMessage message = new SimpleMailMessage();
    message.setTo(mail.getTo());
    message.setFrom(mail.getFrom());
    message.setSubject(mail.getSubject());
    message.setText(mail.getBody());
    message.setSentDate(mail.getSendDate());
    javaMailSender.send(message);
    log.info("Send mail end ");
 }
 }

以下是测试yaml源码:

---
spring:
 mail:
   default-encoding: UTF-8
   host: localhost
   jndi-name:
   username: username
   password: secret
   port: 2525
   properties:
     mail:
      debug: false
      smtp:
       debug: false
       auth: true
       starttls: true
  protocol: smtp
  test-connection: false

我可以从EmailServiceImpl类发送电子邮件,但是当我尝试运行 test 时,它没有收到任何消息。

我尝试了一切,但没有得到任何运气。任何帮助将不胜感激。

谢谢。

标签: springspring-bootjava-8spring-jmsgreenmail

解决方案


我可以从 EmailServiceImpl 类发送电子邮件,但是当我尝试运行 test 时,它没有收到任何消息。

您不应该在测试中收到消息。负责与 SMTP 服务器进行实际通信的低级组件是JavaMailSender,在类中,EmailServiceImpl您确实通过调用发送实际电子邮件:

javaMailSender.send(message);

但是在测试中你嘲笑了那个类:

@Mock
private JavaMailSender javaMailSender;

因此,如果您在调试器中放置一个断点,EmailServiceImpl您将看到该javaMailSender数据字段包含一个模拟。Mock 不应该发送任何东西,它只允许指定期望并稍后验证。它不会发送任何实际的电子邮件。

// in the setup code - setup what do you expect from mock (I assume javaMailSender.send returns void):
 doNothing().when(javaMailSender).send(message);

// in the verification part of the test - make sure that the mock was called once with the params that you expect:
 verify(javaMailSender, times(1)).send(message);

关于 spring 的一个词只是为了澄清 - 在测试中你根本不使用 spring,所以没有加载任何 beans,并且 yaml 文件中没有可用的 spring 配置实际上没有加载。


推荐阅读