One of the biggest hurdles for any kind of UX development is the data. We've all been there: we have design layed out, some features in the backlog and we are eager to start developing our new app. But we are depending on the data from the API.
The usual way to overcome this and not be completely blocked by this situation is to use some static mock data and create our components in some component development environment, e.g Storybook. Having static mock data would allow us to develop some presentational components, but the real meat and potato of our app would need to be developed only after we get the actual data.
The other way is to have the API return some mock data, which we will use in our app, and only when the back-end team provides us with some mock data they can start working on actual features. Again, this is sub-optimal: it slows down back-end team and it puts a lot more pressure on them to get the mock data first and postpone real feature development.
The workflow which would make both teams a lot happier could be to have an agreement on the API spec, which both teams can use as a guide when designing the data model, and to develop its set of features in the order that makes more sense for both sides.
From the front-end perspective, a tool that allows this kind of workflow is Mock Service Worker
, or shorter msw
and that is what we are going to talk about in this post.
Mock Service Worker (msw
)
Simply put, msw
is a tool for API mocking. It mocks API calls by installing a service worker for you which intercepts network calls to the API and calls your registered handler functions instead. You, as a developer, need to worry only about writing handler functions for endpoints your app is reaching to.
It supports both REST and GraphQL APIs, it can delay the response of mocked API endpoints so the endpoint feels more real-life, it has it's own in-memory database with @msw/data
package for more complex querying (e.g, searching, sorting), it can also run mocks in NodeJS environment instead of Service Worker (really useful for testing). Next, let's take a look at which problems msw
can solve and how.
Benefits of using msw
Testing
Imagine a React component that fetches some data from an API and than it renders that data on to the page. What are our testing options? We could mock the function or a library that is doing the fetching, we could mock the underlying fetch
call or we could intercept the network call in some way (e.g, with msw
).
The first approach would give us a confidence that our component is calling a function that should return us data, the second approach is giving us confidence that our component integrates properly with the fetching library (swr
, react-query
, plain fetch
or axios
) and the last approach is giving us confidence that we are making the right HTTP call.
The beauty of intercepting the network call with msw
in our tests is that we are gaining a lot more coverage and thus confidence in our tests, that test reflects real-life way more and we are not coupling our tests with the fetching library. Imagine we needed to change a library we use for making network calls, e.g from swr
to react-query
. Since we are not actually mocking a fetching library in our tests we don't need to change them at all. In any other scenarios listed above, we would need to refactor our tests as well. Double win!
Independent FE development
My first experience with msw
was on a project where I was the only FE developer and I had a BE team of two. We had a really short deadline (1 month) to deliver an app. Both FE and BE were starting from scratch, and the back-end needed to do some work on infrastructure, getting the data sources and writing migration scripts for that data, etc. The client wanted a demo every week to see how the app is coming along. I proposed msw
as a way to unblock my development, we would just need to agree on the data models. As we had clear requirements about how the data should look, that part wasn't that difficult.
Using msw
, we were able to conduct the demo every week with mocked endpoints that looked realistic. Endpoints had a delay of 500ms to return data, the data between pages was connected (clicking on a table row loads relevant details page), searching returns relevant data, etc.
Once the backend team had some endpoints done, I just removed msw
handlers for those endpoints without making any changes to the underlying code. The side-effect is that I had tests that were using the same handlers for realistic tests. msw
was a crucial organizational tool on that project that increased team's velocity and made the biggest impact on the project's success.
Debugging
Every once in a while there is a bug in our code that is happening only when a certain response is returned from an API. If you don't have control over the API (some other team is responsible for it, it's a vendor API) than it means that you would need to somehow change the HTTP response in troubling response. Traditional method in these kind of situations is using an OS proxy app like Charles Proxy
or Wireshark
, but they can be really difficult to setup and to run properly (you have to deal with certificates to see HTTPS calls, etc.).
Alternative is to spin up msw
that mocks the endpoint that you need and to just return the data to stress the app with. It's way, way faster and simpler and you can also use that handler to write a test for that scenario (I'm repeating myself, I know).
Conclusion
In this post I've shared my experience using msw
library in my own projects and what could be potential benefits for you and your projects. I hope you will give it a try. Let me what is your experience using msw
in the comments.
Top comments (3)
Thanks for sharing your experience with using MSW in the wild! Really blows me away to hear that some of the selling points MSW has are paying off and help people ship products with better confidence. Would love to hear more insights from you in the next articles!
Thanks! MSW was really a critical part of the app in the early stage of the product, it really helped with gaining the trust of the client and for gathering the feedback.
I do plan do have another post on the topic that will show the setup and how we used it in real life. Stay tuned!
Please do! Excited to read about it.