Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test JavaMailSender?

I have little problem. I created MailService to send mails. When I run program, it works. All properties to email I have in resources/application.properties. I'm using spring-boot-starter-mail.

@Service
public class MailService {
    private JavaMailSender javaMailSender;

    @Autowired
    public MailService(JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
    }

    public void sendMail(String subject, String messageContent, String recipient)
            throws MessagingException {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
        messageHelper.setTo(recipient);
        messageHelper.setSubject(subject);
        messageHelper.setText(messageContent);
        javaMailSender.send(mimeMessage);
    }
}

But I don't have idea how can I create test for it. I tried something like this, where I use org.jvnet.mock-javamail:mock-javamail, but it doesn't work:

public class MailServiceTest {
    private MailService mailService;

    @Mock
    private JavaMailSender javaMailSender;


    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mailService = new MailService(javaMailSender);
        Mailbox.clearAll();
    }

    @Test
    public void sendMailTest() throws MessagingException, IOException {
        String subject = "Some subject";
        String body = "Some contents.";
        String recipient = "[email protected]";

        mailService.sendMail(subject, body, recipient);
        List<Message> inbox = Mailbox.get(recipient);
        assertTrue(inbox.size() == 1);
        assertEquals(subject, inbox.get(0).getSubject());
        assertEquals(body, inbox.get(0).getContent());
    }
}
like image 512
Mar Mosh Avatar asked Dec 04 '22 22:12

Mar Mosh


2 Answers

I think you are getting unit test / mocking wrong. It seems that you want to create a unit test; but expect the results of a integration test.

What you can do with a unit test here:

  • provide a mocked JavaMailSender (as you already)
  • use verify on that mock later on

In other words: you are mocking the actual sending of a mail. Thus you can't expect that a mail will show up somewhere!

The only thing possible: ensure that the method calls you expect to see actually take place. But that basically leads you to write a test case that simply "re-implements" your production code using verify calls. That isn't too helpful.

Probably you should rather look into a real integration test here. Send a real email; and check a real inbox if that mail shows up there.

like image 29
GhostCat Avatar answered Dec 06 '22 11:12

GhostCat


You can test how MimeMessage was formed with:

public class EmailServiceTest {

    private EmailServiceImpl emailServiceImpl;

    private JavaMailSender javaMailSender;

    private MimeMessage mimeMessage;

    @Before
    public void before() {
        mimeMessage = new MimeMessage((Session)null);
        javaMailSender = mock(JavaMailSender.class);
        when(javaMailSender.createMimeMessage()).thenReturn(mimeMessage);
        emailServiceImpl = new EmailService(javaMailSender);
    }

    @Test
    public void emailTest() {
        String recipient = "[email protected]"
        EmailRequest request = new EmailRequest();
        request.setRecipient(recipient);
        emailServiceImpl.send(request);
        assertEquals(recipient, mimeMessage.getRecipients(RecipientType.TO)[0].toString());
    }
}
like image 82
Justinas Jakavonis Avatar answered Dec 06 '22 13:12

Justinas Jakavonis