How do I mock a REST server with with multiple endpoints in the same test in Java?

Viewed 4682

I'm trying to test a Java method that makes a request to a remote REST server to retrieve some JSON data, extracts an ID from that JSON, then uses the ID to make another request to the same server at a different endpoint.

Using Mockito's MockRestServiceServer, I can successfully mock and test a server that expects a single request to one endpoint, but it seems that I cannot use it to create a server with a set of predefined endpoints with their own expectations and responses.

How do I mock a server with multiple endpoints for the purpose of testing a single function that makes multiple, distinct requests to the remote server?

2 Answers

So I was actually able to solve my problem. The trick is to manually create your own MockRestServiceServerBuilder to build your MockRestServiceServer instead of using the createServer(RestTemplate) or bindTo(RestTemplate).build() methods, like so:

MockRestServiceServer.MockRestServiceServerBuilder builder = 
    MockRestServiceServer.bindTo(restTemplate);
builder.ignoreExpectOrder(true);
MockRestServiceServer server = builder.build();

By doing so, the underlying RequestExpectationManager field in the MockRestServiceServer is initialized as an UnorderedRequestExpectationManager, allowing you to match requests regardless of the order in which they were made. This solved a lot of headaches for me.

My answer assumes you are using SpringBoot but the idea can be applied generically.

Make your class depend on the RestOperations interface so that you can pass a stub when testing.

Class Under Test

public class Foo {
  private final RestOperations restOperations;

  public Foo(RestOperations restOperations) {
    this.restOperations = restOperations;
  }
}

Test

  public void test() {
    Foo foo = new Foo(new MyStub());
  }

Depend on abstractions, not concrete implementations.

Related