1  Summary

ObMimic™ from OpenBrace is a library of plain Java™ implementations of the Servlet API’s interfaces and abstract classes. These are specifically designed for use as ready‑made test‑doubles in “out‑of‑container” unit‑testing and integration‑testing of Servlets, Filters, Listeners and any other code that uses the Servlet API.

ObMimic’s test‑doubles provide complete, accurate, fully‑configurable and fully‑documented plain‑Java simulations of the corresponding Servlet API objects, whilst also providing additional facilities to help with the testing of your code.

We call these test‑doubles “mimics” because unlike mocks or stubs they automatically mimic the full behaviour of the real Servlet API objects. Our aim is for them to be the ultimate set of test-doubles for the Servlet API.

Using ObMimic you can write comprehensive, detailed tests for code that depends on the Servlet API using the same tools and techniques as for normal plain‑Java code, and without having to deploy and run your code inside a servlet container.

In particular:

  • Your tests can obtain ready‑to‑use, fully‑functional HttpServletRequests, HttpServletResponses, ServletContexts, HttpSessions and other such Servlet API objects using plain no‑argument constructors (for example, new HttpServletRequestMimic() to create an HttpServletRequest).
  • You can programmatically configure each “mimic” for all relevant details of the corresponding Servlet API object’s logical state, and for any external factors that affect its behaviour (even where these would be intrinsically fixed or read‑only when running within a servlet container), with ObMimic automatically maintaining consistency between related Servlet API methods.
  • You can pass the appropriate “mimic” instances to your code wherever it needs Servlet API objects.
  • You can inspect the logical state of each “mimic” as necessary to check the results of your tests (even where the relevant information would be inaccessible or write‑only when running within a servlet container).

This includes being able to test your code against (for example) different “init parameter” values and other environmental or configuration settings, different web‑application contents, differences in the behaviours that can vary between servlet‑containers, and different versions of the Servlet API — all under programmatic control within your tests.

ObMimic also lets you selectively record and examine the Servlet API calls made; lets you simulate the various exceptions that Servlet API methods can throw; identifies any Servlet API calls whose behaviour is incompletely or ambiguously defined; and provides a configurable, in‑memory JNDI simulation for any JNDI calls in your code.

Compared to other approaches to testing Servlet API code:

  • There are none of the restrictions, complexities, overheads or delays that arise when trying to test and debug code inside a servlet container;
  • There are none of the limitations or uncertainties of trying to use basic stubs or general‑purpose mocks to simulate the Servlet API (in particular, there is no dependency on the precise sequence of Servlet API calls issued by your code or any code it might call, nor any dependency on your own assumptions and expectations of the Servlet API’s behaviour);
  • There are no dependencies on any particular testing frameworks or web‑application frameworks (so you can use ObMimic with JUnit, TestNG or any other such testing tools, and regardless of whichever web‑application framework you might be using);
  • There is no need to write and maintain test‑doubles of your own.

For further details of how ObMimic compares to various other approaches, refer to the Comparisons page.

There’s a free “Community Edition”, a “Professional Edition” that provides additional features and configuration options for a low per‑developer price; and an “Enterprise Edition” that provides full source code (plus a corresponding build script and comprehensive test suite) together with a licence for up to 100 users.

All editions come with extensive documentation (which is also available online within this website’s Documentation section), including a “Read Me” document that covers system requirements and installation instructions, a Getting Started guide, a set of How To guides (with code examples where appropriate), and comprehensive and detailed Javadoc.

The remainder of this page covers:

2  ObMimic’s “Mimic” Classes

ObMimic’s “mimic” classes are complete and accurate implementations of the Servlet API’s interfaces and abstract classes that can be used outside of any servlet container, and that also provide various additional facilities to support their use in testing.

We call these implementations “mimics” because they accurately mimic the behaviour of the corresponding real Servlet API objects in normal servlet‑container implementations. (In terms of the more widely‑used names and definitions for various types of test‑double, as given for example on the xUnit Patterns website, these “mimics” are somewhat of a cross between a Fake Object and a Test Spy, whilst also being usable as a Dummy Object or Test Stub, offering some of the benefits of using a Mock Object, and having some unique facilities of their own).

You can use these mimics in your tests wherever you need an instance of an HttpServletRequest, HttpServletResponse, ServletContext, HttpSession, ServletConfig, FilterConfig or other Servlet API interface or abstract class. Each mimic provides a complete implementation of all of the relevant Servlet API object’s methods and behaviour, exactly as defined by the Servlet API Javadoc. This includes handling all of the various complex interactions between Servlet API methods, and providing consistent results from methods that affect each other or depend on the same underlying data.

Unlike the “real” Servlet API implementations provided by servlet containers, each mimic:

  • Is a normal Java object that can be used outside of any servlet container and does not depend on any particular servlet container’s internal implementation (and similarly is not tied to any particular testing framework or web‑application framework or toolkit).
  • Includes a simple no‑argument constructor. You can, for example, obtain a complete, ready to use HttpServletRequest with code as simple as “new HttpServletRequestMimic()” (additional constructors and “factory” classes are also provided through which you can construct mimics initialised with particular values or related to each other, for example to create a “paired” HttpServletRequest and HttpServletResponse for a given ServletContext).
  • Is fully configurable: You can programmatically control everything that affects how its Servlet API methods behave and respond (though everything is initialized to valid and reasonable default values, and consistency between related Servlet API calls is always maintained).
  • Is fully examinable: You can programmatically examine all of the effects of Servlet API method calls on the Servlet API object’s logical state, even where the Servlet API itself does not support this (for example, you can examine the content that has been written to an HttpServletResponse’s output, retrieve the entries that have been written to a ServletContext’s log etc).
  • Provides additional features and instrumentation to aid in your testing (as described in Additional Facilities below).

As a result your tests can create, configure, use and examine mimic instances as necessary, and with the appropriate configuration these mimics will provide the correct behaviour across even the most complex sequences of Servlet API calls.

Note that because it can accurately handle arbitrary sequences of Servlet API calls, you can use ObMimic not only in “pure” unit‑testing of individual components, but also in coarser‑grained testing of code that depends on multiple components — even where this includes, for example, the use of filter chains, listeners, request‑dispatching, and third‑party libraries and frameworks that make their own internal calls to the Servlet API.

For example, as described in the ObMimic documentation’s “How To” guide for How to test JSF pages, you can use ObMimic for out-of-container testing of complete JSF pages (including full programmatic control over the ServletContext and other Servlet API objects as usual, and with the ability to access the JSF API via the “FacesContext” object during each test).

3  ObMimic’s “MimicState” Classes

Internally, each mimic instance uses a separate “mimicState” object to represent the logical internal state of the relevant Servlet API object, and provides access to this via a public “getMimicState” method. Each of these mimicState’s support a set of properties and methods for configuring and examining all relevant details of the logical internal state of the mimicked Servlet API object.

Where appropriate, these mimicStates:

  • Include any relevant references to related Servlet API objects (for example, the relevant ServletContext).
  • Use sub‑components to represent common or logically‑grouped sets of details (for example, for sets of “attributes” as used in ServletRequests, ServletContexts and HttpSessions).
  • Use sub‑components to represent the containing web‑application’s deployment‑descriptor settings, the servlet container, and the underlying environment that is being simulated, and through which any relevant details and optional behaviours can be configured.

To a large extent the use of ObMimic hinges on finding your way around each mimic’s mimicState and its subcomponents, and determining how to use their properties and methods to configure each mimic as necessary for your tests and to check the results of your tests.

In addition to representing the logical internal state of its containing mimic, each mimicState object also provides:

  • A constructor that establishes a suitable set of initial, default values for all of its properties and sub‑components, so that newly‑constructed mimics and their mimicStates are immediately ready for use, with valid and reasonable contents.
  • A “clear” method that resets the mimicState back to its initial default values.
  • A “copyFrom” method for deep‑copying of the mimicState. This allows you to easily duplicate mimics; to take “snapshot” copies of mimics at different points during a test; and to restore mimics back to known states.
  • An “equals” implementation for equality‑comparison of mimicState instances. Together with the ability to deep‑copy instances via the “copyFrom” method described above, this allows you, for example, to configure mimics that represent the “expected results” of a test, and then check the final state of the mimics actually used in a test against these “expected results”.

Note that:

  • This approach keeps the methods for configuring and examining the mimic’s logical internal state (and the nature and structure of that state and any validation rules for its properties) quite separate and distinct from the Servlet API methods themselves.
  • Each mimic’s Javadoc for its Servlet API methods defines precisely how the method’s implementation interacts with the properties and methods of the mimic’s mimicState.
  • To help you find your way around the mimicState objects and their sub‑components, the ObMimic documentation supplements the detailed Javadoc for their classes with a separate Overview of MimicState Classes that provides a high‑level summary of the contents of each mimic class’s mimicState.
  • Where a mimicState references a related Servlet API object (for example, the relevant ServletContext), the related object will normally be another ObMimic mimic. However, the use of any other implementation of the relevant Servlet API interface is also permitted. Where necessary you can thus combine the use of mimics with the use of other stubs, mocks and test‑doubles (for example, to introduce the use of one or more ObMimic mimics into an existing test that uses some other type of “stub” or “mock”). Although some ObMimic features and some specific aspects of the Servlet API’s behaviour do depend on internal cooperation between the implementations of the objects involved (and therefore cannot be supported when combining an ObMimic mimic with some other implementation), wherever this is the case ObMimic degrades gracefully in the presence of non‑mimic objects and explicitly documents how this affects its behaviour.

4  Additional Facilities

In addition to being fully configurable and examinable as described above, each mimic:

  • Supports a “history” facility for recording and examining the sequence of Servlet API calls that have been invoked on the mimic, including their arguments and results. This can be programmatically cleared/reset and turned “on” and “off” on each mimic individually, so you can limit it to the calls made during a particular test.
  • Supports a “listeners” facility that can by used to intercept, examine and optionally modify the details and outcome of each individual Servlet API call invoked on the mimic at the point where it occurs, including the ability to examine and modify the method’s arguments and result.
  • Checks for any “ambiguous” calls to Servlet API method, where the Servlet API Javadoc is considered incomplete or ambiguous for that particular call (for example, where a method argument is null but the Servlet API Javadoc does not explicitly specify whether this is valid or how the method should handle it). By default, ObMimic throws a runtime exception from such calls to indicate the specific ambiguity that has been encountered. However, ObMimic can also be configured globally or programmatically to handle such ambiguities (with various levels of specificity) in various other ways (such as ignoring the call, using its own “best guess” interpretation, throwing some specified type of exception etc). In all cases the ObMimic Javadoc specifies exactly what situations are considered ambiguous and the options available for handling each of them. In particular note that this allows you to confirm that your code does not make unwarranted assumptions about the Servlet API’s behaviour, or to at least explicitly recognise where you may be doing so (whilst still permitting you to provide any reasonable behaviour that might be assumed and required by any calls made by any third‑party code that you are using).

ObMimic also allows your tests to programmatically control:

  • Which version of the Servlet API is being simulated (for example, so that you can easily repeat a test against different versions of the Servlet API).
  • How to handle behaviour that can differ between servlet containers or can depend on the servlet container’s configuration or underlying environment (for example, the servlet container’s default response buffer size; the value to be returned by the ServletContext “getServerInfo” method; whether cross‑context request dispatching is supported or not; whether access to request headers using the HttpServletRequest “getHeaders” method is allowed or always returns null; what file‑separator string the Servlet API methods should use; and many other such details).
  • The throwing of the various exceptions that can potentially arise during use of the Servlet API, so that code that handles such exceptions can be tested (for example, to force the throwing of an IOException when writing to a ServletOutputStream; or to force a call to the RequestDispatcher’s “forward” method to fail with an example ServletException).

ObMimic also includes:

  • Comprehensive and detailed Javadoc for its Mimics, MimicStates and all other classes. In particular each mimic’s Javadoc for each of its Servlet API methods specifies precisely how the corresponding Servlet API Javadoc has been interpreted; any ambiguities in the Servlet API Javadoc and the options available for handling these; and how the mimic’s implementation interacts with its “mimicState” and any other relevant ObMimic configuration.
  • An in‑memory JNDI simulation that you can populate programmatically to support any explicit or implied “Environment Naming Context” JNDI look‑ups from the code being tested.
  • Additional classes that you can use to explicitly manage the lifecycle of a mimic instance where this is relevant to the behaviour of the corresponding Servlet API object but is not directly controllable through its Servlet API methods (for example, for “initializing” and “destroying” a ServletContext, including appropriate invocations of any relevant listeners). For full details and to explore the classes available, see the Javadoc for ObMimic’s com.openbrace.obmimic.lifecycle.servlet, com.openbrace.obmimic.lifecycle.servlet.http packages.
  • A mimic for the java.security.Principal interface (as returned, for example, by the HttpServletRequest interface’s getUserPrincipal method).
  • A wide variety of classes and methods that are used within ObMimic and which may be of wider use for the testing of Servlet‑related code or more generally (for example, a “StaticResourceServlet” that writes fixed response content that is supplied to it on construction). For full details and to explore the classes and methods available, see the Javadoc for ObMimic’s com.openbrace.obmimic.support.servlet, com.openbrace.obmimic.support.servlet.http and its supporting com.openbrace.obcommon.* packages.

Note that some of the above facilities are limited to the “Professional” and “Enterprise” editions of ObMimic. For a full list of features and how these vary between ObMimic’s different editions, see the Features page.

5  Example Code

Example code that illustrates the basics of using ObMimic can be found in ObMimic’s Getting Started (Short Version) document.

The same example accompanied by a more complete explanation and commentary can also be found in the Getting Started (Detailed Version) document, together with some additional examples.

Further code examples that focus on particular features and uses of ObMimic (including alternative approaches to various issues) can be found in many of ObMimic’s How To guides.

6  Trying ObMimic

The “Community Edition” of ObMimic is available at no cost and without any need to register, sign‑up to anything, or give us any of your details. Subject to accepting its licence agreement, you can just download and install it, and you’re ready to start.

ObMimic isn’t tied to any particular testing framework, web‑application framework or toolkit, so you can use it in JUnit or TestNG tests or in any other Java‑based tests and independently of any other frameworks, tools or libraries you may be using. Its classes are all contained in a single jar archive with no significant dependencies other than a suitable JDK and the Servlet API itself, so it’s easy to introduce into your projects.

Depending on your code and any existing tests you might have, you don’t even have to dive straight into any extensive use of ObMimic — you can start making simple use of ObMimic in any particular situations where you find it convenient, and then gradually expand its use into more complex situations as you become more familiar with it and as you see fit.

7  Buying ObMimic

If you need the extra facilities that the “Professional Edition” provides (as shown on the Features page), or if you’d just like to support us and ObMimic’s further development, you can buy “per‑seat” licence‑key files that enable these facilities.

If you need a significant number of licences, or if want your own copy of ObMimic’s source code (whether to be able to customize ObMimic yourself, or to reduce any dependency on us as ObMimic’s vendor, or just to aid in the debugging of your code) you can buy the “Enterprise Edition”. This includes all of ObMimic’s source code together with a build script, comprehensive tests, and a licence that permits use of the “Professional Edition” facilities for up to 100 users.