Fake Servers in SinonJs

One of the most powerful features of SinonJs is the ability to create a fake server. This feature is very useful when unit testing a component that's connected to a server via an API. Fake servers let you write real unit tests, where your client side test does not depend on the server side implementation. Instead of relying on a real server, fake servers register your requests and respond them with the proper payload.

Use cases for SinonJs fake servers

Fake servers intercept Ajax requests and store them in an array. The stored requests can be responded in any order with any payload. It is even possible to set up rules to automatically respond requests when certain conditions apply. Therefore, fake servers simplify your automated tests.

The usage of fake servers is not limited to testing: it also makes parallel development of the client and server side code possible, as soon as the API specification is finalized. All you need to do is set up which endpoints need to be intercepted and replaced with fake responses, and which endpoints of the API should still be accessed in a regular way. This way, you can fully develop the client side code before the server side implementation is done.

Creating a fake server

Let's create a WebsiteReportModel and a QuickStatsModel and respond their requests using fake servers.

The SinonJs fake server collects the requests in the fakeServer.requests array. Each request can be responded with arbitrary code, content type and payload in any order. It is therefore possible to test how your application behaves:

  • when your request is successfully responded,
  • when the server returns an error,
  • when the server times out,
  • when concurrent requests are responded in arbitrary order.

Years ago, I identified a very strange behavior in an application having reports both in table and graph mode. While table mode offered just a couple of rows at a time, graph mode displayed all entries between a start and an end date. When switching between table and graph mode quickly back and forth, sometimes graph mode data were loaded in table mode, making the report incredibly long. It turned out that it took more time for the server to respond the graph request than the time difference between sending the last two requests. As a consequence, the application tried its best to display graph data in table mode. The error itself was normally very hard to reproduce, but once SinonJs fake servers were used, reproducing the error became an obvious task: responding the requests was possible in any order. The conclusion was that in case of concurrent requests, it is important to increase testing coverage to make sure any response order works as expected.

Once the restore method of the fakeServer is called, Ajax requests can be sent again.

Fake servers with auto respond rules

When the autoRespond property of a fake server is set to true, the server uses its pre-defined rules to automatically respond the requests it caught.

As soon as you execute the above code, the fake server will automatically respond your request with payload, using the rule defined at the end of step 2.

A request is only responded with success when a rule is defined for the called endpoint. The request will fail otherwise:

Fetching the api/status endpoint failed as the corresponding rule had not been defined.

At the end of the session, the restore method of the fake server should be called to restore original behavior:

Filtering Requests

In this example, we will set the useFilters property of the fakeServer.xhr object to true. This will configure the fake server to pass through some requests the fake server does not want to deal with. These requests can be responded by a real server.

In step 4, the fake server responds the requests just like in the previous example, because the endpoint api/reports/website is not filtered out by the filter function defined in step 2. The endpoint in step 5 is not responded by fakeServer. This time, the real service was used, responding the request successfully.

In step 2, if we removed the negation in the filter function, the request in step 4 would fail because the fake server would not answer it. It does not matter that a rule has been defined for that specific endpoint. The request in step 5 would also fail as the fake server does not contain any predefined rules on how to respond such a request.

Filters are very useful when developing complex applications. Imagine that you have access to all features of an API, except for one simple feature that's the API team has not started. If you wanted to start developing the client side code, you would be able to start development by using the existing API and a fake server defining all the rules you need for developing the new feature.

Use Fake Servers for testing and development

This article demonstrated three use cases for fake servers:

  • Manual response using a fake server: use this option when the sequence of the responses matters when testing.
  • Automatic response using a fake server: use this option when unit testing your application and the sequence of the responses do not matter.
  • Fake server using filters: this use case is mainly for development. In case you used SinonJs for end to end testing, you could exercise one endpoint from end to end, while substituting all the other endpoints with fake requests.

Although SinonJs fake servers come with other features and settings, these are the ones I personally found the most useful when developing and testing a complex application. Feel free to try them out!

This was part eight of the test automation series on Mocha, Chai, and SinonJs. If you are interested in reading more on test automation, check out the complete series by clicking here.

Learn ES6 in Practice

Sign up below to access an ES6 course with many exercises and reference solutions.