This post is a brief write-up about how Mock Service Worker
radically improved testing experience and -surprisingly- overall development flow on a couple frontend projects I recently worked on.
Testing: mock API to support test
I initially chose Mock Service Worker
just as a Fetch mock replacement, for the only reason that it intercepts network requests at the network layer enabling mocking any requests including Axios's XMLHttpRequest
ones.
msw
approach favors building API mocks in a centralized way so that all tests run against the same set of mocks. (Still, any test can extend msw
mock handlers on the fly, when strictly necessary).
As the projects have scaled, msw
mocks ended up simplistically replicating most of the consumed API. This opened to...
Development: using the same mocks
Since msw
handlers replicate most of API dependencies, I could run the same mocks used by tests in the browser to run the development environment. For free.
Running tests and development environment with the same mocks turned out to be a huge improvement for both testing and development.
Debugging tests
Broken tests could be debugged more easily be replicating the testing scenario in browser. Same mocks means same application state in tests and browser.
Decouple local development from API
Developing in the browser using local mocks resulted in a faster and more flexible development flow: local mocks take almost no time to load but the keep the exact same async flow of real API responses.
Local mocks are easy to extend or change, therefore replicating a new API scenario is trivial.
I ended up using local mocks most of my development time and contacting the actual API in very rare cases.
Storybook
In case you used Storybook, msw
integrates seamlessy with it, too.
MSW inspector: asserting against mocked requests
msw
encourages an end-to-end testing approach, decoupled from code's implementation details, which I also recommend:
Instead of asserting that a request was made, or had the correct data, test how your application reacted to that request.
Even though, I sometimes found it necessary asserting against a specific sent request. Like ensuring that a post/put
request is issued with proper payload.
For this reason msw
provides an API to listen to intercepted requests.
msw-inspector
is a tiny utility I wrote to inspect msw
intercepted requests and enable any testing framework to assert against them. It's open source and published as an npm package.
expect(mswInspector.getRequests('http://my.url/path')).toHaveBeenCalledWith({
method: 'POST',
headers: {
'my-header': 'value',
},
body: {
'my-body': 'value',
},
query: {
'my-query': 'value',
});
Top comments (2)
Hey, Andrea! Thank you for writing this articleโa superb job done!
I like your take on the request assertions and the
msw-inspector
utility. We've been cooking something similar internally to allow people to assert request/response calls as well. I would love to get your feedback on our solution once it lands!Keep up the great work on writing. You're awesome.
Hi Artem, thanks for your feedback!
msw-inspector
is public and quite battle tested. I'm considering making it more flexible by letting users the power to customize the returned inspected data.Feel free to ping me on GitHub.