Without creating another class that I can inject. Is it possible to mock javax.mail.Transport
so I can do some mock testing of the Transport.send()
method on Java EE 7?
Following up on Bill Shanon's solution since Dumbster does not have a currently working Maven Central artifact, I used GreenMail.
Then I used the following code:
final GreenMail mailServer = new GreenMail();
mailServer.start();
final Properties mailSessionProperties = new Properties();
mailSessionProperties.put("mail.smtp.port", String.valueOf(mailServer.getSmtp().getPort()));
final javax.mail.Session mailSession = javax.mail.Session.getInstance(mailSessionProperties);
testObject.setMailSession(mailSession);
That way testObject
does not need to change even if it has a static call to Transport.send(message)
.
If what you want is to not call Transport.send while testing then you could use this:
@RunWith(PowerMockRunner.class)
@PrepareForTest(javax.mail.Transport.class)
public class MyClassTest {
@Before
public void before() throws Exception {
suppress(method(Transport.class, "send", Message.class));
}
}
see also https://groups.google.com/forum/#!topic/powermock/r26PLsrcxyA
Another approach that hasn't been discussed is to wrap calls to Transport.send(message) in a class that delegates the call. It's a bit of overhead in your code base, but it allows you to mock your delegating class and create the outcomes you want.
public class TransportDelegator {
public void send(Message msg) throws MessagingException {
Transport.send(msg)
}
}
Then mock TransportDelegator as you would in whatever framework you are using.
Yes. On way is to use Mockito. https://code.google.com/p/mockito/
public class CategoryDAOTest {
private Transport transport = Mockito.mock(Transport.class);
@Test
public void sendMessage() throws MessagingException {
transport.sendMessage(null, null);
}
}
Or, using annotations to create the mock:
@RunWith(MockitoJUnitRunner.class)
public class CategoryDAOTest {
@Mock
private Transport transport;
@Test
public void sendMessage() throws MessagingException {
transport.sendMessage(null, null);
}
}
I created a new wrapper class and Mocked it with Mockito. This prevented me from adding PowerMock to my project.
public class MyTransport{
public void send(MineMessage msg) throws MessagingException{
javax.mail.Transport.send(msg);
}
}
In side test class we just need
@Mock
private MyTransport myTransport
This will do nothing when is called. You may also want to verifiy myTransport is getting called.
Mockito.verify(myTransport).send(correctMsg);
Another approach is to use a fake SMTP server such as Dumbster. The JUnit tests in the JavaMail source workspace use a similar approach.
You can try JavaMail Mock2 https://github.com/salyh/javamail-mock2
It primarily focused on IMAP/POP3 but SMTP Mock is also available. In your case the "Fullmock" mode is a good choice. Its also available in maven central.
If you are on linux / osx you can use python to create a mock smtp server, like that:
python -m smtpd -n -c DebuggingServer localhost:1025
Then it is enough if you connect to port 1025 on localhost and you can send emails. The Python code can be started by simple ProcessBuilder call (How to run Unix shell script from Java code?).
This is How I did after hours of research, I was sending a list of attachments paths along with email to my method. everything workd fine
@Test
public void testWhenMigrationReportSentSuccessfully() throws Exception {
mockStatic(Transport.class);
PowerMockito.doNothing().when(Transport.class, "send", any(Message.class));
service.report(anyList(), "[email protected]");
}
© 2022 - 2024 — McMap. All rights reserved.
GreenMail
is that your test can then verify that the expected email was sent. I've added in my tests things like this:MimeMessage[] messages = mailServer.getReceivedMessages(); assertEquals(1, messages.length, "Failed to receive registration email"); assertEquals(1, messages[0].getHeader("To").length, "Malformed To headers in received registration email"); assertEquals(user.getEmail(), messages[0].getHeader("To")[0]);
– Highness