Skip to content

Latest commit

 

History

History
91 lines (67 loc) · 3.92 KB

README.md

File metadata and controls

91 lines (67 loc) · 3.92 KB

Apollo Test

This is a library containing tools for testing your Apollo applications.

Include the maven dependency in your project pom.xml

<dependency>
  <groupId>com.spotify</groupId>
  <artifactId>apollo-test</artifactId>
  <version>${apollo.version}</version>  <!-- (version not needed with apollo-bom) -->
  <scope>test</scope>
</dependency>

If you get MethodNotFound exceptions from Hamcrest move this dependency to the top. E.g. mockito and junit adds their own (older) versions of hamcrest to the classpath.

Introduction

When testing your apollo service code there are some things that need some extra attention. Things like the fact that your code uses the RequestContext.requestScopedClient() to make service calls and that the whole request handler returns a CompletionStage. You'll have to mock the RequestContext instance and set up interaction rules for how each request should be identified and what the response should be. Furthermore you should have actual asynchronous responses instead of just returning a CompletableFuture.completedFuture(T) if you want to test how the transformations actually compose when responses come in after the transformations are set up in the handler.

This library aims to help with testing your services with a few helpers: ServiceHelper and StubClient.

Let's write some tests

An example how tests that call this endpoint and mock the brewery calls would be written using the test library.

public class MinimalAppTest {

  private static final String BREWERY_ORDER_URI = "http://brewery/order";
  private static final String ORDER_REPLY = "order0443";
  private static final ByteString ORDER_REPLY_BYTES = ByteString.encodeUtf8(ORDER_REPLY);

  @Rule
  public ServiceHelper serviceHelper = ServiceHelper.create(MinimalApp::init, "test");

  public StubClient stubClient= serviceHelper.stubClient();

  @Test
  public void shouldRespondWithOrderId() throws Exception {
    stubClient.respond(Response.forPayload(ORDER_REPLY_BYTES)).to(BREWERY_ORDER_URI);

    CompletionStage<Response<ByteString>> replyFuture = serviceHelper.request("GET", "/beer");
    String reply = replyFuture.toCompletableFuture().get().payload().get().utf8();

    assertThat(reply, is("your order is " + ORDER_REPLY));
  }

  @Test
  public void shouldFailForBadStatusCode() throws Exception {
    stubClient.respond(Response.of(StatusCode.IM_A_TEAPOT, ORDER_REPLY_BYTES).to(BREWERY_ORDER_URI);

    CompletionStage<Response<ByteString>> replyFuture = serviceHelper.request("GET", "/beer");

    StatusType statusCode = replyFuture.toCompletableFuture().get().getStatusCode();
    assertThat(statusCode.statusCode(), is(Status.INTERNAL_SERVER_ERROR.statusCode()));
  }
}

Here we have a unit test that creates a ServiceHelper that will use MinimalApp::init to create our routes. From the helper we can get a StubClient for setting up replies to outgoing requests. The actual tests then should be pretty self-explanatory. They simply use stubClient.respond(...) and its overloads to setup different request-reply scenarios. Then they make the call to our endpoint using serviceHelper.send(...) and verify the response.

Hamcrest Matcher Utilities

There are a couple of handy utility classes that can help you write your tests more succinctly:

More tests