Often when I’m working near the top of the test automation pyramid, I find myself needing to test interactions with outside services such as SMTP servers.
On projects in the past, I’ve been able to leverage java tools such as greenmail, which lets me have logic like this.
public class MailerTest {
private Greenmail greenmail
@Before
public void startGreenmail() {
greenMail = new GreenMail();
greenMail.start();
}
@After
public void stopGreenmail() {
greenMail.stop();
}
@Test
public void testYourSendingCode() throws Exception {
new Mailer().send("to@localhost.com", "body");
assertEquals("body", GreenMailUtil.getBody(greenMail.getReceivedMessages()[0]));
}
}
This library is particularly useful as it allows interrogation of sent mails directly from the test. However, I have had trouble finding an equivalent gem for ruby development. However, there is the fantastic command line tool, mailtrap. Mailtrap is written in ruby and:
Mailtrap waits on your chosen port for a client to connect and talks just enough SMTP protocol for ActionMailer to successfully deliver its message.
Unfortunately, mailtrap does not play nicely with automated tests. It writes out captured emails to the filesystem, and there is no easy way to start, stop or interrogate a server in memory. However, mailtrap and greenmail have acted as the inspiration for mailcrate. Mailcrate is designed to be run from your test code and allows interrogation of sent mails from the test itself. For example:
require 'mailcrate'
describe Mailer do
before do
@mailcrate = Mailcrate.new(2525)
@mailcrate.start
end
after do
@mailcrate.stop
end
it 'should use Mailcrate to send mails' do
mail = Mailer.welcome_email('a@b.com')
mail.deliver
@mailcrate.mails[0][:from].should == 'from@example.com'
@mailcrate.mails[0][:to_list].should include 'a@b.com'
@mailcrate.mails[0][:body].should include 'Full of awesomeness.'
end
end
Mailcrate has been published as a gem and can be used by running:
gem install mailcrate
Mailcrate is still rather immature. Any feedback would be welcomed, both here on this blog or its github page.