• 1.17.1

Mock Servlet Container

MkContainer is a simple lightweight Java servlet container that can act as a mock server-side of your application, in order to test your RESTful client, for example:

public class ClientTest {
  @Test
  public void sendsHttpHeadersCorrectly() {
    MkContainer container = new MkGrizzlyContainer();
    container.next(
      new MkAnswer.Simple("hello, world!")
        .withHeader("Content-Type", "text/plain")
        .withHeader("Server", "mock")
    );
    container.start();
    new JdkRequest(container.home())
      .through(VerboseWire.class)
      .header("User-Agent", "My Super HTTP Client")
      .fetch();
    container.stop();
    MkQuery query = container.take();
    MatcherAssert.assertThat(
      query.headers(),
      Matchers.hasEntry(
        Matchers.equalTo("User=Agent"),
        Matchers.hasItem("My Super HTTP Client")
      )
    );
  }
}

Let's see what's happening here. First, a new instance of MkContainer is created, with a Grizzly-based implementation MkGrizzlyContainer:

MkContainer container = new MkGrizzlyContainer();

The container is not yet started and doesn't know what to reply when a new HTTP request comes in. We should add at least one instance of MkAnswer to its queue of ready-to-be-dispached answers:

container.next(
  new MkAnswer.Simple("hello, world!")
    .withHeader("Content-Type", "text/plain")
    .withHeader("Server", "mock")
);

It's possible to add more instances of MkAnswer, using this method next(). They will be returned by a running container one by one in response to incoming HTTP "queries" (which will be recorded by the container as instances of MkQuery and available later through method take()).

Now it's time to start the container on a randomly allocated TCP port (you can also use a fixed port number, but random allocation is preferred):

container.start();

Then, we're making a request to a running container, getting its main entry URI by container.home() (VerboseWire is used in order to make HTTP request and response details visible in log):

new JdkRequest(container.home())
  .through(VerboseWire.class)
  .header("User-Agent", "My Super HTTP Client")
  .fetch();

Then, we stop the container:

container.stop();

Now it's time to check what was received by the container before it was stopped. All "queries" received are recorded in the container in chronological order. They may be retrieved using container.take() method:

MkQuery query = container.take();

Finally, we can make assertions about this query:

MatcherAssert.assertThat(
  query.headers(),
  Matchers.hasEntry(
    Matchers.equalTo("User=Agent"),
    Matchers.hasItem("My Super HTTP Client")
  )
);

MkGrizzlyContainer depends on Grizzly Servlet Webserver, and this dependency is required in your pom.xml:

<dependency>
  <groupId>com.sun.grizzly</groupId>
  <artifactId>grizzly-servlet-webserver</artifactId>
  <version>1.9.10</version>
  <scope>test</scope>
</dependency>