The Mock Service Worker (MSW) API mocking library allows developers to test web applications without using an actual back-end, setting up a mocking server, or stubbing native http
/https
/fetch
implementations. MSW mocks both Rest and GraphQL APIs. MSW received the JavaScript Open Source Awards this year.
An increasingly popular approach to testing UI components consists of rendering and exercising the component under test as much as possible in the same conditions and in the same way as a real user would. The rationale is to avoid testing implementation details linked to the component’s internal API. The mentioned approach seeks to decrease the likelihood of having to change tests, not in response to a change in specifications, but in response to a change in implementation of the component.
However, as user actions are exercised on an actual rendered component, they may trigger real effects (e.g., remote data fetching, API calls) that need to be mocked or stubbed.
While a mocking server is an actual server, the mocking server may differ from the production server in ways that affect the confidence derived from the testing (e.g., different architecture, or technologies). A mocked server may also require to modify the component code to point requests to the mocked server endpoint.
The native stubbing approach avoids modifying the component code for testing purposes. However, having tests passing against an altered version of a native fetch
browser method does not completely guarantee that the same tests will pass against the unaltered version of fetch
.
MSW allows developers to mock Rest and GraphQL APIs without having to modify the component code or stubbing native http
/https
/fetch
implementations.
MSW documentation explained how MSW works in the browser:
This library registers a Service Worker that listens to the application’s outgoing requests via the
fetch
event, directs those requests to the client-side library, and sends a mocked response, if any, to the worker to respond with.
[…]
As MSW intercepts requests at the network level instead of the application level, developers can use the fetching library of their choice (e.g., native fetch
, axios
, react-query
). For the same reason, developers should still implement end-to-end tests to exercise the actual network layer.
Mocked responses can be observed in the browser dev tool. The following code example:
// src/mocks.js
// 1. Import mocking utils.
import { setupWorker, rest } from 'msw'
// 2. Define request handlers and response resolvers.
const worker = setupWorker(
rest.get('https://github.com/octocat', (req, res, ctx) => {
return res(
ctx.delay(1500),
ctx.status(202, 'Mocked status'),
ctx.json({
message: 'Mocked response JSON body',
}),
)
}),
)
// 3. Start the Service Worker.
worker.start()
and a GET https://github.com/octocat
request will result in a mocked response visible in the browser’s Network tab:
Other open-source libraries provide functionalities similar to MSW. Nock, an HTTP server mocking library, only supports Node.js. Nock, however, provides also an assertion API. JSON Server creates an actual HTTP server from a JSON file. JSON Server works in Node and the browser. None of the previous two libraries support mocking GraphQL APIs.
MSW received the JavaScript Open Source Awards this year in the Most Exciting Use of Technology category. MSW is open-source software distributed under the MIT license.