reduxjs / redux-toolkit

The official, opinionated, batteries-included toolset for efficient Redux development
https://redux-toolkit.js.org
MIT License
10.64k stars 1.15k forks source link

[Vitest - RTK Query - MSW] Store not updating in specific case after upgrade to RTK v2 and react-redux v9 #3973

Open followynne opened 9 months ago

followynne commented 9 months ago

Hello everyone,

in our project we use Vitest as the test runner and MSW to mock endpoint calls.

Issue

When I upgrade react-redux: 8.1.3 => 9.0.4 and RTK: 1.9.7 => 2.0.1, some tests start to fail.

We have a selector that access an RTK Query in the following way:

const selectUserResult = userApi.endpoints.getUser.select();

export const selectUser = createSelector(
  selectUserResult,
  (userResult) =>
    userResult.data ?? { Id: "", Email: "", Permissions: [] as Array<string> },
);

In the real application we call the getUser endpoint before rendering the React application and it works fine when we upgrade the versions.

During testing we execute the api call manually and mock it out with MSW; with the v8/v1 versions the selector updates correctly while, on the latter versions, the selector doesn't change after the first render.

Steps to reproduce

I created this CodeSandbox sample with the minimum amount of code to reproduce the issue.

If you run the test terminal with the sandbox as-it-is, you'll see the successful tests; if you upgrade the versions the tests will fail (you'll see in the logging the different behavior).

Additional info

If it's not a bug, can you kindly point us to a different approach to get the API results in a selector function?

Thanks for the help 🤗

markerikson commented 9 months ago

Thanks for filing and the repro! I'll try to look at it when I get a chance, but I'm on travel and it may be a while.

followynne commented 9 months ago

No worries, thanks for checking in already! We're not in an hurry to update and can wait when you have some free time 😁

EskiMojo14 commented 9 months ago

for what it's worth, if you add enhancers: (getDefaultEnhancers) => getDefaultEnhancers({ autoBatch: false }) to your store setup, the tests pass again.

The autoBatchEnhancer is added to the store by default in RTK 2.0, and your test seems to function in such a way that it doesn't account for this batching of subscribers.

phryneas commented 9 months ago

So probably adding another await Promise.resolve() before making the assertions might already make it pass without disabling the autoBatching behaviour (which you should probably keep on).

followynne commented 9 months ago

@EskiMojo14 @phryneas

thanks a lot for the answer! I gave a try to both suggestions and I can confirm that

phryneas commented 8 months ago

Could also need a small timeout or something - usually when writing tests for React, you'd use findBy... type queries or the waitFor helper to wait until the DOM changed accordingly, so it's not important to be accurate to a scpecific ping.