msw icon indicating copy to clipboard operation
msw copied to clipboard

Jest/Testing-Library with RTK-query, msw fails to reset handlers when testing for error case after success case.

Open ymoon715 opened this issue 3 years ago • 10 comments

Prerequisites

Environment check

  • [X] I'm using the latest msw version
  • [X] I'm using Node.js version 14 or higher

Node.js version

v16.13.1

Reproduction repository

https://github.com/ymoon715/rtk-query-msw

Reproduction steps

clone the repo at https://github.com/ymoon715/rtk-query-msw

npm i
npm run test

Current behavior

I have my tests to reset the handlers after every test. I ran into an error when testing for both success and error cases. If i test error case FIRST, then success SECOND, it all passes.

However, if i test success case FIRST, then error case SECOND, error case fails.

I am using server.use() to test both success and error cases. I have 4 different test files to showcase that testing error case first THEN the success case always works, where as testing success case first THEN the error case always fails

Expected behavior

server.resetHandlers() to successfully reset the handlers, or for us to be able to test for error case after successful cases.

ymoon715 avatar Aug 29 '22 17:08 ymoon715

Hey, @ymoon715.

Did you try running your test with the --runInBand option for Jest?

jest --runInBand

MSW doesn't support parallel runs (see #474), so you need to make sure you run your tests sequentially. I believe once you add this option to your test script the issue will be gone:

https://github.com/ymoon715/rtk-query-msw/blob/9f761fc110d96446207c9218ced90faadd5b4558/scripts/test.js#L52

Could you please try this out?

kettanaito avatar Sep 02 '22 10:09 kettanaito

Hey, @ymoon715.

Did you try running your test with the --runInBand option for Jest?

jest --runInBand

MSW doesn't support parallel runs (see #474), so you need to make sure you run your tests sequentially. I believe once you add this option to your test script the issue will be gone:

https://github.com/ymoon715/rtk-query-msw/blob/9f761fc110d96446207c9218ced90faadd5b4558/scripts/test.js#L52

Could you please try this out?

Thanks for the reply @kettanaito I just tried --runInBand and it made no difference.

ymoon715 avatar Sep 02 '22 17:09 ymoon715

Then it’s either shared state issue that introduces between-test dependency, or a bug.

kettanaito avatar Sep 03 '22 09:09 kettanaito

If the following tests succeeds with nock, would you consider this a msw issue? These tests were written on create-react-app. I also tried it with bunch of clean up methods including resetting the reducer.

ymoon715 avatar Sep 07 '22 12:09 ymoon715

I got the same error with react query, any solution?

jucian0 avatar Sep 28 '22 20:09 jucian0

For me the problem was that React Query by default retry when a request fails, so, I disabled that in tests, @ymoon715, probably RTK works in the same way.

jucian0 avatar Sep 29 '22 17:09 jucian0

I was running into the same issue when fetching data using SWR. My issue was I was fetching data with the same key, so the first request's response is cached, and was returned to me in subsequent test runs.

I was able to resolve my issue by providing a clean SWR provider at every render like this:

<SWRConfig value={{ provider: () => new Map() }}>
  { children }
</SWRConfig>

From what I can see in the RTK docs, looks like RTK does something similar and caches response data based on some key. You might be able to solve your problem if you figure out how to invalidate cache and re-fetch for each test case even if you're using the same key.

SaltedCaramelCoffee avatar Oct 19 '22 00:10 SaltedCaramelCoffee

I was running into the same issue when fetching data using SWR. My issue was I was fetching data with the same key, so the first request's response is cached, and was returned to me in subsequent test runs.

I was able to resolve my issue by providing a clean SWR provider at every render like this:

<SWRConfig value={{ provider: () => new Map() }}>
  { children }
</SWRConfig>

From what I can see in the RTK docs, looks like RTK does something similar and caches response data based on some key. You might be able to solve your problem if you figure out how to invalidate cache and re-fetch for each test case even if you're using the same key.

Tried removing/resetting cache afterEach. This did not work.

ymoon715 avatar Jan 05 '23 21:01 ymoon715

@ymoon715 I think you need to add this to your RTK Query API

export const api = createApi({
  ...
  keepUnusedDataFor: process.env.NODE_ENV === 'test' ? 0 : 60, <----- THIS HERE
});

So that data is not cached when using tests

DominicGBauer avatar Jul 19 '23 06:07 DominicGBauer

If cache is the problem use this solution from another issue

beforeEach(() => {
  store.dispatch(pokemonApi.util.resetApiState());
});

https://github.com/mswjs/msw/issues/251#issuecomment-1274474669

Same solution but on stackoverflow from rtk query contributor: https://stackoverflow.com/questions/67999073/how-to-clear-rtk-query-cache-in-tests-between-requests-when-using-msw-and-jest

augusticor avatar Aug 18 '23 00:08 augusticor