Revolving around the core of technology
Testing application before rolling them to clients is crucial for any platform. Many applications require generating email as part of their workflow. Imagine you need to test an application that sends emails to genuine customers with accurate data, but none of these customers should actually get these emails. This page gives you step-by-step instructions on how to accomplish this task.
Almost every programming language has frameworks for Unit Testing. In fact, many integrated development environments (IDE) support unit testing without any third-party integration. Such IDEs include Microsoft Visual Studio, Eclipse, and others. Regardless of the programming language or IDE you use, the method to perform unit testing is a two-step process:
ClientRegistration
, which has a method called confirmEmail
, which
sends a confirmation email to the client with further instructions.
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ClientRegistrationTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testConfirmEmail() {
new ClientRegistration().confirmEmail(); //Sends an email to an SMTP server.
//TODO: Have to confirm if the email is sent correctly.
//Refer to step 2 for this.
}
}
The code you see above calls the method confirmEmail
but does not check if the email is actually sent.
You will need to download a small utility called DevNullSmtp, which contains a dummy SMTP server that accepts emails from the code that needs to be tested. DevNullSmtp is written in Java and therefore, you will need JRE to run it. We recommend using JRE 1.8.
Before testing begins, you need to configure the SMTP server in your application to this dummy SMTP Server.
Assume in production, the hostname of your SMTP server is mail.yourcompany.com
. There are two
ways to change this value:
mail.yourcompany.com
to
localhost
.hosts
file at your OS level and
skip a DNS lookup. The location of hosts
file on Windows is C:\Windows\System32\drivers\etc\hosts and on
Linux it is /etc/hosts. Now that all the prerequisites are discussed, let's talk about the next step.
Once an email is sent (step 1), the next step is to verify the email was indeed received by the SMTP server and the body of the message is correct. This is where DevNullSmtp comes into picture, which is a dummy SMTP server with the ability to optionally save incoming emails to a folder on the disk.
There are two ways to spawn DevNullSmtp:
setUp()
method of JUnit and terminate it in tearDown()
method.
Refer to the documentation for DevNullSmtp to see how to start DevNullSmtp as a stand-alone application.
The second method is more interesting because you can spawn DevNullSmtp when testing starts and terminates when done.
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ClientRegistrationTest {
Process proc = null;
@Before
public void setUp() throws Exception {
//Spawn a new process for DevNullSmtp on port 25 and save emails to /testEmails folder
String[] cmdarray = {"java", "-jar", "DevNullSmtp.jar", "-console", "-s", "/testEmails"};
proc = Runtime.getRuntime().exec(cmdarray);
//Alternatively, call com.synametrics.devnull.DevNullSmtp.main() method
//which will run DevNullSmtp in the same process as JUnit.
}
@After
public void tearDown() throws Exception {
if(proc != null) {
proc.destroy(); //Terminate DevNullSmtp once testing is over.
}
}
@Test
public void testConfirmEmail() {
new ClientRegistration().confirmEmail(); //Send an email, which will be saved in /testEmails folder
//Confirm a new *.eml file is saved in /testEmails folder.
File folder = new File("/testEmails");
assertEquals(1, folder.listFiles().length);
}
}
The setUp() method in JUnit framework is used to start DevNullSmtp, which is configured to listen for incoming emails on
TCP/IP port 25 and will save incoming emails to /testEmails
. The spawned process is saved in the member variable proc.
Another way to start DevNullSmtp is to just call it's main
method, provided the JAR file is in the CLASSPATH.
However, this method is only available if my original test code is also in Java. You won't be able to call main if you're trying to
perform unit testing in any other language, such as C#.
Calling proc.destroy()
terminates the spawned process, terminating DevNullSmtp.
new ClientRegistration().confirmEmail();
Ideally, the above line should have generated an email that is received by the dummy SMTP Server: DevNullSmtp. The remainder of the
function checks the newly saved file in /testEmails
folder.
Using DevNullSmtp is an excellent way to test outbound emails. Messages sent to DevNullSmtp do not get delivered to any recipient. Instead, it can be used to perform unit testing on any application that sends emails.