I would like to know what would be the best way to do unit testing of a servlet.
Testing internal methods is not a problem as long as they don\'t refer to the servl
Most of the time I test Servlets and JSP's via 'Integration Tests' rather than pure Unit Tests. There are a large number of add-ons for JUnit/TestNG available including:
This is a JWebUnit test for a simple Order Processing Servlet which processes input from the form 'orderEntry.html'. It expects a customer id, a customer name and one or more order items:
public class OrdersPageTest {
private static final String WEBSITE_URL = "http://localhost:8080/demo1";
@Before
public void start() {
webTester = new WebTester();
webTester.setTestingEngineKey(TestingEngineRegistry.TESTING_ENGINE_HTMLUNIT);
webTester.getTestContext().setBaseUrl(WEBSITE_URL);
}
@Test
public void sanity() throws Exception {
webTester.beginAt("/orderEntry.html");
webTester.assertTitleEquals("Order Entry Form");
}
@Test
public void idIsRequired() throws Exception {
webTester.beginAt("/orderEntry.html");
webTester.submit();
webTester.assertTextPresent("ID Missing!");
}
@Test
public void nameIsRequired() throws Exception {
webTester.beginAt("/orderEntry.html");
webTester.setTextField("id","AB12");
webTester.submit();
webTester.assertTextPresent("Name Missing!");
}
@Test
public void validOrderSucceeds() throws Exception {
webTester.beginAt("/orderEntry.html");
webTester.setTextField("id","AB12");
webTester.setTextField("name","Joe Bloggs");
//fill in order line one
webTester.setTextField("lineOneItemNumber", "AA");
webTester.setTextField("lineOneQuantity", "12");
webTester.setTextField("lineOneUnitPrice", "3.4");
//fill in order line two
webTester.setTextField("lineTwoItemNumber", "BB");
webTester.setTextField("lineTwoQuantity", "14");
webTester.setTextField("lineTwoUnitPrice", "5.6");
webTester.submit();
webTester.assertTextPresent("Total: 119.20");
}
private WebTester webTester;
}
Updated Feb 2018: OpenBrace Limited has closed down, and its ObMimic product is no longer supported.
Another solution is to use my ObMimic library, which is specifically designed for unit testing of servlets. It provides complete plain-Java implementations of all the Servlet API classes, and you can configure and inspect these as necessary for your tests.
You can indeed use it to directly call doGet/doPost methods from JUnit or TestNG tests, and to test any internal methods even if they refer to the ServletContext or use session parameters (or any other Servlet API features).
This doesn't need an external or embedded container, doesn't limit you to broader HTTP-based "integration" tests, and unlike general-purpose mocks it has the full Servlet API behaviour "baked in", so your tests can be "state"-based rather than "interaction"-based (e.g. your tests don't have to rely on the precise sequence of Servlet API calls made by your code, nor on your own expectations of how the Servlet API will respond to each call).
There's a simple example in my answer to How to test my servlet using JUnit. For full details and a free download see the ObMimic website.