Skip to content

Creating and maintaining external server stubs

I watched one of your presentations on youtube where this repository is presented.

One point you mention close to the end is that you do not like testing against a real server in your unit test. Sometimes it is not even yet available (because under development) but the main reason is that you mention that a server could break the test for an unrelated reasons (break the test or make it flaky). I couldn’t agree more.

We have plenty of libraries/components to mock a distant web server. Some are more complex, others are really low level (WireMock, microcks, …). I think you use something included in the spring framework and you just return a json file present in your resources folder for a given read request.

That's fine to illustrate the concept, but I was wondering if you could elaborate a bit more on how you write and maintain such mocks. I am interested in the case where you consume an external existing service (exactly like swapi in your case). Also the service is not only a read-only, the interaction is more complex (like doing read but also update and delete calls)

Inspired by your talk I started to explore the proxying and capturing capability of mock-server. I pushed some code here mockserver-record-replay

The main idea is that the mock-server is either:

  • Proxying the real server (should be used only during development/modification of the test)
    • Before each test configuring the proxy: source
    • Capturing the HTTP calls after each test: source
  • Reusing the captured HTTP calls (should be used in the CI and when the test is unchanged): source

In an ideal setup the code managing the mock-server library should be more generic (probably wrapped in a JUnit Extension) and would probably clean the captured HTTP calls (for example make the captured JSON stable in case of a re-run or have ids that match the hard-coded one in the test)

I am wondering why nobody really discusses this point anywhere. In cases like this I am always thinking that I am certainly re-inventing the wheel, because this problem is quite generic and must have been discussed somewhere.

What is your opinion/approach on this question?