If I want to test frontend code (e.g. react SPA) that queries the backend and I stub out the responses from the backend using sinon fake server/fake XHR, then what happens if the backend code changes?

If the backend changes then the frontend tests will continue to pass, but the functionality may well be broken. It is possible that these stubs would get updated when the backend changes but it is also possible that this could be missed.

What are the best practices surrounding this issue?

Note: Apologies if this question has already been answered extensively, which I suspect it has. I cannot seem to figure out the right terms to search if it does exist.

  • 1
    You already know the answer to this. If your backend changes in such a way that the stubs are invalidated, then you need to change the stubs to conform to the new backend implementation. You can identify these discrepancies during integration testing. – Robert Harvey Jun 5 '18 at 21:22
  • So when I am changing the tests for the backend I would also need to make sure to change any tests that stub out those routes? What about people that potentially change the code in the future? It just seems like it's unlikely to happen in a very complex project. Perhaps with a simple project. – Adam Thompson Jun 5 '18 at 21:32
  • 1
    What about people that potentially change the code in the future? -- If there's a best practice, it is to put a process or policies in place that require review of the affected test suites when a relevant change occurs. There's no magic here. – Robert Harvey Jun 5 '18 at 21:37

When testing the interface between two parts, the easiest way is to test those parts together, i.e. perform integration tests. If you want to test each part in isolation (i.e., perform component/unit tests) then your tests will contain a duplicate description of this interface, which may diverge from the real interface.

One possible solution is to structure these tests so that these tests can be verified against the real interface. E.g. by recording real interactions, and replaying them during your tests. When you capture an interaction for a web API, you have a HTTP request and response. This is great, because it's easy to replay those with a fake server or client.

  • Test the client against a fake server. This server verifies that the client's request match the recorded request, and responds with the recorded response.
  • Also, test these responses against the real server. Run the recorded requests against the real server, and verify that the real response matches the recorded response.

If these tests fail, the interface has changed unexpectedly. You must then fix the client or server, and re-record the failing interactions.

Diagram of the various tests

The advantage of using recorded interactions over pure integration tests is that the recordings can be replayed faster, and can be easier to debug. The suite of recordings is shared between the server and client, but both can be developed independently – you do not need to run the client tests when changing the server, as long as the recordings still match.

If this is supposed to work well, you will have to set up some automation for capturing the interactions. Ideally, you can run your client test suite in a recording mode that saves the response when run against the real backend. This doesn't necessarily have to be supported by your test framework, as this recording can be done in a proxy HTTP server. You will also have to strip out irrelevant details such as timestamps, so don't save the raw requests. Often, deleting various headers and filtering the body through some regexes is all that's needed.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.