personal experiences and code :)

Tuesday, October 24, 2006

get Wiser with SubEthaSMTP

You won't think it should be so difficult to write effective test cases for the bits of your application where you have to send/receive emails.

Sample use case:

You have a 2-step registration process where after a user has submitted their info, they are sent a challenge token (via email) to validate the submission/make sure the email address is actually in use (and that they have access to it), before you add them to your 'users' table.

Ideally, to test this little piece of functionality, you need to be able to give your test mua a fake smtp port, have a dummy server listening on that port, have a convenient way of starting this server, retrieving messages it has to transfer, be able to retrieve all the usual suspects from a sent message (sender, receiver, subject, content etc), and be able to make assertions against these and your test data.

A long time ago, I found dumbster; I figured it solved the author's problems when he/she wrote it then, but just couldn't cut it for what I wanted to use it for.

So I went asearching, and found greenmail, which seemed to relieve me of the pains I was having with dumbster, although it still felt kinda kludgy; for instance, this is a snippet taken of the examples doc on the greenmail page:

[code]
servers = new Servers(ServerSetupTest.ALL); servers.start();
//use random content to avoid potential residual lingering problems final String
subject = servers.util().random(); final String body = servers.util().random();

//wait for max 5s for 1 email to arrive
assertTrue(servers.waitForIncomingEmail(5000, 1)); //Retrieve using GreenMail API
Message[] messages = servers.getReceivedMessages();
[/code]


the servers.waitForIncomingEmail(5000, 1) bit is clearly kludgy; it also seemed to treat ccs as sent mail, so if you sent one mail and cc'ed it to 10 people, then you had to remember to test for 11 mails to be sent by the mta; i found workarounds for this, and all in all it caused me far less pain than dumbster, so I was actually quite happy with it... at least until Geert pointed me to Wiser

From the Wiser page:

[code]
Using Wiser is trivial:

Wiser wiser = new Wiser();
wiser.setPort(2500); // Default is 25
wiser.start();

Now, use a mail client to send email to your Wiser server. To get your JavaMail messages out of the Wiser server, just use this code:

for (WiserMessage message : wiser.getMessages())
{
String envelopeSender = message.getEnvelopeSender();
String envelopeReceiver = message.getEnvelopeReceiver();

MimeMessage mess = message.getMimeMessage();

// now do something fun!
}
[/code]


It really doesn't get simpler (and wiser than that); and yes, writing effective email test cases has, thanks to Wiser, become quite simple; and fun too :)

cheers.

-- eokyere :)

6 comments:

J said...

glad you like it! -jon (co-author)

Anonymous said...

Wiser rocks.

Subetha SMTP rocks.

Anyone who needs a flexible and non-intrusive way to receive mail in Java, or a dead simple way of testing that sending mail works, should check it out.

Wael said...

Thanks for sharing. Just to point out that it is not necessary to use waitForIncomingEmail(). waitForIncomingEmail() is useful if you're sending (possible big) stuff in a different thread.

plus, greenmail is not only a SMTP server but also a SMTPS, POP3, POP3S, IMAP, and IMAPS.

eokyere said...

wael,

thanks for the comment. i must admit that I did not try to find what the best way of doing this was with greenmail--i assumed the example on the project page was the best way to go.

how would u go about simple smtp with greenmail, then?

i'm still using wiser for basic smtp testing, but if i have to do other tests it doesn't support, then it's good to know that greenmail might bail me out.


thanks,
-- eokyere :)

Anonymous said...

Wiser is fantastic. My only frustration is that when I did not know about Wiser and was google-ing for a simple smpt serve to use for mocking, the only one that turned up in my google searches was Dumbster. It was only by dumb luck that two weeks later after suffering with the numerous problems with Dumbster, I accidentally saw the comment by the author of Wiser in a forum entry on the Dumbster site.
In summary, let's all get the word out about Wiser and try to make it less likely people will stumble on Dumbster and not realize it's been replaced in the hearts and minds of java developers by Wiser.

Anonymous said...

Why the wiser can't recieve any email? I wrote something like the following. The wiser is always empty. what's more should I do?

thanks for your response!



protected Wiser wiser=new Wiser();

wiser.setPort(25);
wiser.start();

browser.open(url);

browser.type("emailaddress", a valid email address);

browser.type("Password1", "qatest01");

browser.type("Password2", "qatest01");

browser.type("FirstName", "jessie");

browser.type("Text2", "zhang");

browser.click("Submit1");

Thread.sleep(5000);

for (WiserMessage message : wiser.getMessages())
{
String envelopeSender = message.getEnvelopeSender();
String envelopeReceiver = message.getEnvelopeReceiver();
}
//the code never run into this loop because the wiser is always empty