Skip to content
Chris James edited this page May 22, 2015 · 9 revisions

The problem

You are making a service which has to work with a HTTP API developed by another team. Multiply this by 100 because.. microservices.

Considerations

  • You want to have some integration tests, but you don't want to tie your own build down to an external service so you will want to have a fake server which acts like the API.
  • You want to have consumer driven contracts so that if a breaking change is made by the API, both parties know about it and can deal with it
  • Before going live you want to stress test your service with a life-like environment. A normal fake service would be too reliable.
  • Because you have to do this a million times, you'd prefer not to duplicate the logic of given a http request, give me this response in both integration tests and consumer driven contracts.
  • You prefer to write code that does things, not make you less paranoid about breaking changes made by other teams.

Obviously, mockingjay is the hammer to solve all problems. Install it

Define the integration point as configuration

---
 - name: Test endpoint
   request:
     uri: /hello
     method: GET
   response:
     code: 200
     body: '{"message": "hello, world"}'
     headers:
       content-type: text/json

Easy!

Check your configuration is accurate

A common problem with fake servers is that they can diverge from what the real server actually does. This can mean your build is green but your software wont work. Mockingjay doesn't let this happen.

$ mockingjay-server -config=myconfig.yaml -realURL=http://some-real-api.com

Now that you know your configuration is compatible with the real server, you can now write integration code against it, reasonably confident it will work.

Now might be a good idea to send this configuration to the API creators (if you can) so they can add this command to their CI pipeline so they know if they create a breaking change. You should also wire it into your own build.

## Running your fake server

$ mockingjay-server -config=example.yaml

Testing performance

Mockingjay is the fastest server on earth, and is far more reliable than real APIs. So running as normal wont be very helpful if you are trying to stress-test your service. Thankfully you can make mockingjay act erratically by sending a meddling monkey at it.

Define another yaml file like this:

---
# Writes a different body 50% of the time
- body: "This is wrong :( "
  frequency: 0.5

# Delays initial writing of response by a second 10% of the time
- delay: 1000
  frequency: 0.1

# Returns a 404 30% of the time
- status: 404
  frequency: 0.3

# Write 10,000,000 garbage bytes 10% of the time
- garbage: 10000000
  frequency: 0.09

I don't know how reliable or not your downstream API is, so it might be worth experimenting with various configurations to make sure your service is robust enough.

$ mockingjay-server -config=myconfig.yaml -monkeyConfig=monkey-business.yaml

Configure your service to point at mockingjay then do some testing. According to your configuration your service will have to deal with the downstream flakiness, just like how it will have to do in production.

It's hard to predict the nature of downstream problems, so make sure you have really good monitoring so you can understand the problems you face and then you can simulate them easily on a local environment with mockingjay.

Changes

APIs evolve and sometimes make breaking changes. If you have the CDC check in CI you will know when this happens. Simply update the yaml file and then your integration tests will fail. Fix them and then everything should just go green. By keeping the information of the contract in one file, rather than dispersed in scripts you can keep on top of an expanding set of microservices easier.