DEV Community

Cover image for Bringing together testing and development environment with Mock Service Worker
Andrea Carraro
Andrea Carraro

Posted on • Updated on

Bringing together testing and development environment with Mock Service Worker

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',
});
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
kettanaito profile image
Artem Zakharchenko

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.

Collapse
 
toomuchdesign profile image
Andrea Carraro

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.