Mocking server resources in Frontend development

Zenobia Gawlikowska
EcoVadis Engineering
6 min readAug 25, 2020
People laughing in front of laptops

Mocking server resources is very often a necessity during development. This might be due to various reasons: the server is down or unavailable, or your API is still under development and not fully functional. You might not be able to afford waiting for the problem to be resolved or you might want to plan Frontend development in parallel with Backend development using a predefined contract.

Those are valid reasons and they might make you look for solutions. So, how would you go about solving this problem?

Some off-the-shelf options

First, you would need to either find a ready-made mock library or write your own. Let’s see what options are available.

Requests can be mocked on the server-side, by a plugin in the browser or in the application itself. Let’s see that more in detail.

One possible option would be to use a browser plugin, such as Requestly¹. Here is an article describing this approach:

Requestly allows the interception of server requests in the browser and redirects them to an alternative location, such as a local server with static JSON files. This setup would at minimum require setting up a static server (using node.js Express or any other server serving static files). While this is fine for your local development, working in a team would require that each developer create a local setup on each machine, which is not so practical. Ideally, you would like to be able to share the configuration between the users.

If you are looking for libraries which enable server resource mocking on a node.js server, a library called nock² comes to mind. It allows you to mock server requests made by a script running on a node server. This might be a fine solution for unit testing purposes, when testing components which are dependent on external server requests. Mocking removes the need to have any real network connectivity and real access to the resources. This increases the reliability, speed and relevance of the unit tests. A way of testing React components using nock is described here: https://itnext.io/nock-it-out-of-the-park-http-mocking-for-react-42ec927f83e0

Another possibility is Service Mocker³, a mocking solution using service workers. This is worth looking into, but it is not ready for prime-time as of this writing.

Working towards a custom solution

All this is fine and good, but what if you just want to run your application on localhost as a user, simulating an end-to-end experience, even though your backend is not ready? The endpoints that you need either don’t exist completely, or return an older version of the API, one that you cannot use. You might need some new kind of data while developing, in order to test how your application reacts to it. At the same time, it would be nice if the setup was part of the codebase itself and was as unobtrusive as possible, while having a low barrier of entry. Only the required parts would be mocked („mock as you go”), while all the rest would work as normal. A request to a missing mocked resource should just redirect to the original, while the consumer code would be unchanged. A representation of the request payload also needs to be taken into account, in order to allow different responses to different request parameters.

Using observables

Let’s see how the above requirements could be solved in the context of a real-world application using React, Redux and Rx.js observables, all bundled with Webpack.

Note: in this article we are not going to discuss the way to set up Redux with observable middlewares. For an in-depth discussion about this topic, please see:

Our mocking solution required injecting requests for mocked resources into original observable streams. When in mock mode, the application would first attempt to resolve a mocked data stream and serve it to the consuming code, or — if it fails — it would fall back on the original data stream. This can be accomplished with the catchError rxjs operator. This is a visual representation of the stream generated by this operator:

Source: https://rxjs-dev.firebaseapp.com/api/operators/catchError

So, in order to achieve our goal, we need to combine two observable streams: the mocked data stream and the original data stream. If the first fails, the second takes over. Below is a simple implementation of this concept in a function called ajaxWithMock which wraps a simple ajax observable with a mocked ajax observable.

Next, we need to use the redux-observable⁴ library to plug our middlewares:

What remains to be done, is to attach our middleware to the redux flow:

The consumer code in the epic itself can now be used without any knowledge of the underlying mock system. Just use ajax calls to the original resource as usual! If a mocked resource is present, the response will contain mocked data. Normal error handling for the original resource will still work.

The code that we have now attempts to send requests to our mocked server URL before trying to send a request to the actual endpoint. In the example below, you will see original URLs with folder structures, as well as mock URLs with flattened name structures (slashes have been replaced with underscores). The mocked files contain a suffix which will be explained further in this article. Here is how this looks in the network console:

As you can see, some requests were satisfied directly from the localhost because a mock file was present where expected, while others attempted to retrieve a resource from the localhost, failed with a 404 and proceeded to connect to the original resource, just like we planned. This has an important benefit for the users of the mock system: they do not have to mock all of the endpoints in order to start using mocked resources. All they need to do is to mock the resources they need at a given moment. This greatly helps with easy adoption in the team.

Handling request parameters

So, now we have our mock infrastructure in place. However, what is missing is any handling of the request parameters. So let’s take care of that.

This requires some thought. If a static file server is to be used, it is better to avoid the processing of POST requests with all of their parameters. At the same time, we want to be able to mock POST and GET requests in a transparent manner, taking into account the parameters passed in the payload and in the URL.

This can be accomplished by using a hash digest of the payload, in order to create a string representation of whatever was passed to it.

Note: The common.js require format was used here, so that our hashing function can be used both in node.js scripts and in the frontend application built on top of Webpack.

Assuming that the static files are served from http://localhost:3001, the mocked URL can be constructed this way:

So, a request with a specific payload will be transformed in such a way:

A GET request of this type: https://example.com/company/getAllCompanyCategories?language=english will be transformed into: http://localhost:3001/company_getAllCompanyCategories_CBCDDD.json where CBCDDD is a hashed representation of the query string parameters.

What remains to be done, is to create static JSON resources and serve them from the requested locations. This can be done manually just by placing appropriately named files in the required locations or via scripting. However, this is not covered by this article.

--

--