Introduction

ObMimic from OpenBrace Limited is a library of fully-configurable concrete implementations of all of the Servlet API’s interfaces and abstract classes, for use as “test doubles” in “out-of-container” testing of servlets, filters, listeners and any other code that uses Servlet API classes. We call these implementations of the Servlet API classes “mimics”, as they accurately mimic the behaviour of normal servlet-container implementations of the corresponding Servlet API classes.

With ObMimic, you can use normal Java code (for example, within normal JUnit or TestNG test cases) to create instances of HttpServletRequest, HttpServletResponse, ServletContext, HttpSession, and other Servlet API interfaces and classes for use in your tests, and can configure and inspect these instances as necessary — without any need to deploy your code into a servlet container or use complex “in-container” testing tools, and without any networking overheads.

Installation

To install ObMimic:

  • Unzip the ObMimic-1.2.001.zip archive into the location where you wish to install ObMimic. This will result in an “ObMimic-1.2.001” directory structure at that location.
  • Create an OBMIMIC_HOME environment variable set to the path of the ObMimic installation’s root directory (that is, its “ObMimic-1.2.001” directory).
  • If you have a “Professional” or “Enterprise” licence for ObMimic, place the licence file into the ObMimic installation’s /licence subdirectory.

Adding ObMimic to Your Project

To make ObMimic available within a project:

  • Add the ObMimic installation’s /lib/obmimic.jar to the classpath of the code that will be using ObMimic (for projects using Maven™, see the accompanying “How To” guide How to add ObMimic to a Maven-based project).
  • If not already present, add a suitable Servlet API or Java EE API library for version 2.4, 2.5, 3.0 or 3.1 of the Servlet API to the classpath of the code that will be using ObMimic (that is, a “servlet-api.jar”, “javaee.jar” or other such library that provides the Servlet API itself, excluding any that are deliberately restricted to compile-time use only).
  • If you are using Java SE 5 and are obtaining the Servlet API from a library other than a full Java EE library for Java EE 5 or higher then an additional “Common Annotations” library will also be needed.

For more precise details of these requirements, and where to obtain the necessary libraries if you do not already have them, refer to the System Requirements section of ObMimic’s Read Me document.

You should also ensure that you have convenient access to the ObMimic Javadoc located at /docs/api within the ObMimic installation. Ideally, any IDE you are using should be configured to show this as the Javadoc for the “obmimic.jar” archive.

More generally, the use of a modern Java IDE that supports “code completion” and integrated display of Javadoc is strongly recommended, as this provides the easiest way to find your way around the ObMimic classes and Javadoc whilst working on your code.

You may also find it useful to ensure that you have convenient access to the ObMimic installation’s docs/pages/MimicStateSummary.html document (which provides outlines of all “MimicState” classes) and docs/pages/howto/index.html (which provides a set of “How To” guides).

Note that whilst ObMimic itself is compatible with Java SE 5 onwards, other libraries that you are using may impose higher requirements (for example, if you are using a Servlet 3.1 or Java EE 7 API library this will itself require the use of Java SE 7 or higher).

Using ObMimic

Once you have added ObMimic to your project, you can use it to construct, configure and inspect “mimic” instances of Servlet API interfaces and abstract classes as desired, and use these in your test cases wherever necessary.

Use of ObMimic within a test typically consists of creating the necessary mimic instances, configuring their mimicStates as required for that particular test, passing the mimic instances to the code that is being tested, and then inspecting their mimicStates as necessary to check the results of the test.

Specifically:

  • You can construct instances of the various “mimic” classes provided by the com.openbrace.obmimic.mimic.servlet and com.openbrace.obmimic.mimic.servlet.http packages using their no-argument constructors. You can use such “mimic” instances wherever an instance of the corresponding Servlet API interface or class is needed.
  • You can configure and examine each mimic instance’s “internal state” by means of its mimicState property, as returned by its getMimicState method. The Javadoc for each mimic class’s Servlet API methods include detailed explanations of each such method’s interpretation of the corresponding Servlet API Javadoc, and the method’s interaction with the mimic’s mimicState.
  • If you have a valid “Professional” or “Enterprise” licence, you can also use each mimic instance’s mimicHistory property to optionally record the sequence of Servlet API method calls and results for that mimic for subsequent examination; or you can use each mimic instance’s mimicListeners property to install listeners to examine (and even optionally modify) the Servlet API method calls and results for that mimic as they occur.
  • You can use ObMimic’s configuration properties to control which version of the Servlet API is simulated by ObMimic, how ObMimic handles Servlet API calls that it regards as ambiguous (that is, where the Servlet API Javadoc does not explicitly specify the exact behaviour required), and various other aspects of ObMimic’s behaviour. These configuration properties can be specified in ObMimic’s configuration file (by default, the ObMimic installation’s /config/config.properties file), or via Java system properties, or programmatically during the use of ObMimic (in particular, this allows you to vary these values during tests). However, note that this is subject to many of these properties only permitting non-default values when a valid “Professional” or “Enterprise” licence is present.

Example

To illustrate the basics of using ObMimic, the following code shows a fairly minimal example that invokes a servlet with an HTTP “GET” request that has a particular request parameter and an existing request attribute, after first initializing the servlet with a minimal/default ServletConfig instance. The response’s resulting status code and body content are then retrieved for subsequent checking.


  import com.openbrace.obmimic.mimic.servlet.http.HttpServletRequestMimic;
  import com.openbrace.obmimic.mimic.servlet.http.HttpServletResponseMimic;
  import com.openbrace.obmimic.mimic.servlet.ServletConfigMimic;
  import javax.servlet.Servlet;
  import javax.servlet.ServletException;
  import java.io.IOException;

  ...

  /* Create the request and configure it as needed by the test. */
  HttpServletRequestMimic request = new HttpServletRequestMimic();
  request.getMimicState().getRequestParameters().set("name", "mike");
  request.getMimicState().getAttributes().set("x", 1);

  /* Create the response. */
  HttpServletResponseMimic response = new HttpServletResponseMimic();

  /*
   * Create and initialize the servlet to be tested (assumed to be a class
   * called "MyHttpServlet"), using a dummy/minimal ServletConfig.
   */
  Servlet myServlet = new MyHttpServlet();
  try {
      myServlet.init(new ServletConfigMimic());
  } catch (ServletException e) {
      ... failed with unexpected ServletException ...
  }

  /* Invoke the servlet to process the request and response. */
  try {
      myServlet.service(request, response);
  } catch (ServletException e) {
      ... failed with unexpected ServletException ...
  } catch (IOException e) {
      ... failed with unexpected IOException ...
  }

  /*
   * Retrieve the response's resulting status code and body content, as
   * examples of how the resulting state of the relevant mimic instances
   * can be examined.
   */
  int statusCode = response.getMimicState().getHttpStatusCode();
  String bodyContent = response.getMimicState().getBodyContentAsString();

  ...
      

Further Information

Getting Started (Detailed Version) expands on the contents of this document, including more extensive commentary and notes on the above example and some additional, more extensive examples.

Further information can also be found in: