How to clear RTK Query cache in tests between requests when using MSW and Jest?

Viewed 4046

I'm using Redux Toolkit and RTK Query with MSW for mocking, but I seem to be getting back the same data when trying to return an error in tests. I suspect this is an issue with RTK Querys caching behavior, and have tried to disable it with these options to the toolkit createApi method, but they don't seem to address the issue:

keepUnusedDataFor: 0,
refetchOnMountOrArgChange: true,
refetchOnFocus: true,
refetchOnReconnect: true,

In the MSW documentation it gives examples of how to solve this when using other libraries: https://mswjs.io/docs/faq#why-do-i-get-stale-responses-when-using-react-queryswretc

// react-query example
import { QueryCache } from 'react-query'

const queryCache = new QueryCache()

afterEach(() => {
  queryCache.clear()
})

// swr example
import { cache } from 'swr'

beforeEach(() => {
  cache.clear()
})

How could I achieve the same when using Redux Toolkit and RTK Query?

3 Answers

I can recommend giving the RTK Query tests a read: https://github.com/reduxjs/redux-toolkit/blob/18368afe9bd948dabbfdd9e99b9e334d9a7beedf/src/query/tests/helpers.tsx#L153-L166

This is what we do:

  const refObj = {
    api,
    store: initialStore,
    wrapper: withProvider(initialStore),
  }
  let cleanupListeners: () => void

  beforeEach(() => {
    const store = getStore() as StoreType
    refObj.store = store
    refObj.wrapper = withProvider(store)
    if (!withoutListeners) {
      cleanupListeners = setupListeners(store.dispatch)
    }
  })
  afterEach(() => {
    if (!withoutListeners) {
      cleanupListeners()
    }
    refObj.store.dispatch(api.util.resetApiState())
  })

So you are looking for dispatch(api.util.resetApiState())

Building on the above answer, this is what I did in my app:

beforeEach(() => {
  const { result } = renderHook(() => useAppDispatch(), { wrapper });
  const dispatch = result.current;

  dispatch(myApi.util.resetApiState());
});

wrapper here is the providers for Redux and other context.

SOLUTION: This will immediately remove all existing cache entries, and all queries will be considered 'uninitialized'. So just put the below code into onClick or according to your scenario so when you hit an enter request will go and cache would also be clear. below here api is your name of an api which you would set in your rtk query in store.

dispatch(api.util.resetApiState());

For more info please have a look in documentation https://redux-toolkit.js.org/rtk-query/api/created-api/api-slice-utils

Related