Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 855
niemelsa Avatar asked Sep 21 '25 09:09

niemelsa


2 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())

like image 187
phry Avatar answered Sep 22 '25 22:09

phry


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.

like image 25
Mason Embry Avatar answered Sep 22 '25 23:09

Mason Embry