Hosting Mock Services for Continuous Development

Many modern software projects has a dependency on a service layer such as mobile applications and websites communicating with a backend service or API. In an ideal world the service will be ready and stable before the frontend development starts. This is unfortunately rarely the case and more often than not the front end and API layers will be in development at the same time.

This presents a problem since the frontend development requires a stable API to test against. This is where mocking is useful. A mock service will provide a stable API responding with mocked data. Mocking is also useful for testing specific test cases and increasing test coverage.

Mocking is useful in cases where you need to stay productive when your API layer is non-existent, still under development or unstable. Mocking also allows for test cases to be created which can not be reproduced accurately on the API layer such as edge cases and service failures.

When designing the service layer we make use of contract first designs since multiple applications and a website needs to make use of the same service. The contract describes the available operations on the API including the format of each request and response . The contract should ideally remain unchanged in order to prevent rework on all the frontend platforms. Each platform is developed by a separate team and developers. The benefit of contract first is that the example requests and responses can be defined very early in the API development lifecycle. This means that the mocks can also be created early. Usually the contract is enough to get frontend development started.

Currently each developer has their own approach to develop without a working API in place. For some developing with only the service contract is acceptable, others might run a mock server on their own machine and some refuse to start the frontend before the service is implemented at all.

To eliminate this problem we propose delivering a mocked service together with each API contract. This mock service will be hosted centrally and made accessible to everyone who needs to integrate with the API. Furthemore, any developer can contribute and add additional mocks.

Requirements

The mock server’s main requirement is that it should enable configurable mocked responses based on the service contract. Since multiple developers depends on it, it should be available centrally and anyone should be able to update or add mocked data.

The mocks should be able to handle different scenarios and simulate bad service behaviour such as error responses and time delays.

The hosted mock service must be executed as a Web application.

Implementation

There is a large variety of projects and applications available which will allow for a mocked service to be created including

We specifically look at SOAPUI and WireMock since both of them are open source and the developers in the organisation is already familiar with them.

Fiddler can act as a proxy which will log and redirect requests to the actual service. It’s AutoResponder feature is extremely useful and it can be set up to respond with mocked data which can be imported from the actual service responses logged earlier. Unfortunately there is no way to deploy Fiddler as an standalone web application.

SOAPUI as WAR

Don’t be fooled by the name. Even though the server depends on the SOAPUI library, it can mock almost any kind of response, including REST and it is simple to import definitions from WSDLs, RAMLs, Swagger and others. SOAPUI remains a popular choice for API testing.

Its application user interface is straightforward to use and makes it easy for anyone to define the mocks and different scenarios, even if you’re not a developer.

SOAPUI has a convenient feature where you can export the test suite and mocks as a deployable WAR file. This feature had some limitations when deployed to our Weblogics due to conflicting libraries.

SOAPUI is open source, so we created our own Spring web app which will use SOAPUI’s server. Basically the SOAPUI dependency had to be included and the server properties had to be initialised.

Add the compiled SOAPUI dependency. We had conflicting libraries so that had to be excluded.

Configure web.xml

And finally we configure weblogic.xml to prefer org.apache.commons which was another issue when running the WAR generated by SOAPUI.

Now we can simply include the SOAPUI project file in WEB-INF/soapui as specified by the projectFilepropery of the Servelet. Anyone can contribute to this project and update the mocks and scenarios. The same project can be used for running a MockServer on your localhost or for running the WAR on a hosted server.

SOAPUI can easily import definitions for services from WSDLs, RAMLs and Swagger. If the example requests and responses is defined in the contract, it will be included automatically as mocks when creating the SOAPUI MockServer. This is really convenient since no manual mocking is required.

Importing RAMLs requires the RAML plugin.

WireMock as WAR

WireMock is available as a standalone JAR file which can be executed. It loads mappings and __files from the file system. This is good for local development but we required something which can be hosted on a Weblogic. We created another web app similar to the SOAPUI one.

Include the WireMock dependency

Configure web.xml to make use of the WireMockHandlerDispatchingServelet

The only work that remains then is to move the mappings and __files directories into WEB-INF/wiremock as defined in the WireMockFileSourceRoute property. This can now be deployed as a WAR.

Any developer can contribute to this repository and update the mappings and mocks.

In order to get this running on Weblogic properly ensure that the Weblogic is configured to allow Archived Real Path Enabled. This can be updated on the console by selecting your Domain and the Web Application tab. Enable Archived Real Path Enabled right at the bottom and hit SAVE.

Future work

The mock service can act as a proxy which will intelligently route requests to the actual service if it’s available or alternatively return a mocked response. By doing so, the mocked definitions can be created automatically by using the actual service’s responses.