msw: `server.use()` or `server.resetHandlers` do not appear to be working within/between tests
Describe the bug
server.use() or server.resetHandlers do not appear to be working within tests.
I have a setupTests file that is appropriately calling resetHandlers (confirmed with logging) after each test.
When using a server.use statement to override a route payload like so:
server.use(
rest.get('myUrl', (req, res, ctx) => {
return res(ctx.json([]));
})
);
I would expect the result to return as an empty array. My main handlers file is setup similarly:
rest.get('myUrl', (req, res, ctx) => {
return res(ctx.json(mockDataArray));
})
When running all my tests, I see my mock data, and can log it to the console in the actual component implementation.
When running as part of a test suite, I do not get the overridden empty array that I want, I see the original list from the handlers.
The bug I think I’ve found is that if I run the test as it.only then I see the correct empty array and my test passes. My component logs out the empty array as the fetched data I was expecting. Running the tests completely by itself seems to fix the issue.
I’m hoping this is just a silly mistake on my part.
Environment
msw: 0.19.5nodejs: 12.16.1npm: 6.13.4
Please also provide your browser version. n/a
To Reproduce
Steps to reproduce the behavior: I attempted to reproduce this behavior using the react example project, but haven’t been able to yet.
Expected behavior
I have a setupTests file that is appropriately calling resetHandlers (confirmed with logging) after each test. When using server.use to setup a route override, I should get the payload assigned (as one would expect from the docs as well as the example project.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 6
- Comments: 28 (9 by maintainers)
For anyone coming to this who is using react-query. You will need to add
I have tried as above and it works. Let me know if I’m wrong
Hi @roy-dendro I think that
ApolloClientis caching you responses. So after the first test your response is cached and not executed again.Just export the
new QueryClientyour React Query QueryClientProvider uses and use that one in your tests, like so:Worked for me.
Or, make sure to use
queryClient.clear();before you set any new (updated) handler in between tests, like below. Or else, React Query seems to pick something from the cache.Hope this helps others, struggled with this for too long 😂
It’s in the type definitions
Hey! Thanks for reaching out with this. Let me share some insights on what may help in triaging this issue.
Ensure single server instance
The list of request handlers (
rest.*) is bound to a server instance. Calling.use()and.resetHandlers()operates on the respective instance. Here’s the recommended way of setting up theserverfor tests:Isolate
Isolating a single test to fix an issue is usually a sign of shared state between tests. Apart from the list of request handlers, there may be other state at place, which we can find out. What I’d usually to is
.skipeach test one-by-one, and see what makes the problematic test pass. That does not mean the skipped tests is the issue, but it may lead us to finding the root cause of it.Please, try to set up a minimal reproduction scenario/repository, so we could take a look. Thank you.
This ended up being a cache issue. I was using SWR for the tests in question and I needed to add cache clearing and deduping to fix it. Thank you for walking through the issues to consider, and thanks for @roy-dendro for the reproduction and jogging my mind that I needed to think about the cache!
Here’s what I ended up doing that solved it: https://github.com/vercel/swr/pull/231#issuecomment-591614747
I appreciate your help and quick response.
The api from react query requires you to define a “new” cache in entry point. How do you reset it in every test iteration?
it’s not a problem 😃 the important thing is that the problem is solved. We are here trying to help other and make others help us 😄
I’ve been running into the same issue as well. Let me try and make a reproduction.
We should really create an FAQ point mentioning cache invalidation for such request clients.
This bit me as well. Thank you for the solution. I imagine using Apollo Client is pretty common with
mswso might be nice to include that detail somewhere in the docs. Happy to PR that if you want.Thanks for getting back at such a short notice. We’ll checkout your reproduction repository and let you know on any technical insights we find. Stay tunned.
I was strugglin with this in relation to RTK query. Indeed, the cached requests were my problem, too.
This thread helped me ro realize that. The solution for RTK query is to do
between my tests
Hi, I’d like to add to this, because just like @nicholascm, I’ve encountered the error and created a repo… where it didn’t happen. However I did go through with more testing, and I was able to reproduce a case which I cannot explain right now.
https://github.com/MrGuiMan/msw-handler-override
here you can see that the test that overrides mygraphql query doesn’t work. Skipping the test before it allows it to pass, and moving the third test before it does allow it to pass too. The mechanics of it elude me completely. My best guess is that the first call starts an outstanding request that causes a race condition, but that’s as far as my udnerstanding goes.
@kettanaito any insight would be very appreciated. Thanks
I’m seeing a similar issue recently. I have 2 tests in a file ( A and B ), the first test uses the standard handlers (no server.use) , the second uses a
server.usehandler. Test case B always fails because it is using the standard handlers and disregardingserver.use. If I comment out the test case A, then test case B passes.server.useis the very first line in test case B.We have this configuration for our project as well:
@kettanaito @philals @dgurns @marcosvega91 @roy-dendro I’m unable to use two server.use() get API success call instances
Here I’m conditionally unordered rendering list item or a select field depending on the items being returned in the GET API endpoint, but I’m unable to use the response in two different describe blocks, mock server just renders the whichever block is written first instead of running both the API
getcallsStep1.test.js
server.js
handlers.js