You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To test this component I created 2 different tests (Component.test.js) in which I use react-mock-store to mock my store.
Case 1: Mock item with ID 1 and value 1
Case 2: Mock item with ID 1 and value 2
When I create a store by calling mockStore with these items directly everything works as expected.
it("Case 1 - renders value 1 for item 1 when offering new object to mockStore", async () => {
const store = mockStore({
items: [
{
id: 1,
value: "Value 1"
}
]
});
render(
<Provider store={store}>
<Component />
</Provider>
);
expect(await screen.findByText("Value 1"));
});
it("Case 2 - renders value 2 for item 1 when offering new object to mockStore", async () => {
const store = mockStore({
items: [
{
id: 1,
value: "Value 2"
}
]
});
render(
<Provider store={store}>
<Component />
</Provider>
);
expect(await screen.findByText("Value 2"));
});
Case 1 returns value 1 and Case 2 returns value 2 👍
Now, in my real app I have other parts of my state that I have to mock so I start from a common object (initialState) and append these items to it. I recreated that here as Case 3 and 4:
const initialState = {
items: []
};
it("Case 3 - renders value 1 for item 1 when offering copied object to mockStore", async () => {
let state = initialState;
state.items = [
{
id: 1,
value: "Value 1"
}
];
const store = mockStore(state);
render(
<Provider store={store}>
<Component />
</Provider>
);
expect(await screen.findByText("Value 1"));
});
it("Case 4 - renders value 2 for item 1 when offering copied object to mockStore", async () => {
let state = initialState;
state.items = [
{
id: 1,
value: "Value 2"
}
];
const store = mockStore(state);
render(
<Provider store={store}>
<Component />
</Provider>
);
expect(await screen.findByText("Value 2"));
});
Now Case 4 fails because the selector returns the value from Case 3 (value 1).
Some observations:
running only the last test does succeed
initialState is const so it should not be able to carry over data from Case 3 to Case 4
if I print out the state of the failing test before creating the mockStore it show the correct item (value 2)
if I skip createSelector and just use useSelector it does work correctly:
I think it is because, under the hood, reselect will check the equality of your input arguments first, before checking the extracted output arguments.
In Case 1 and 2, the references of the initialState passed into mockStore are different, so the references of state in your useSelector are different, itemForId will recalculate a result based on the differenct state.
In Case 3 and 4, the references of the initialState are the same, therefore itemForId will use the result cached in Case 3 when running in Case 4.
You won't hit such problem if you're using redux because each time you dispatch an action, a root state with a new reference will give birth under the hood.
Your other observations will make sense based on the theory above.
I'm poor at English. Let me know if I have made mistakes.
I have a weird issue which is causing some of my tests to fail.
I am not sure if this is a problem with reselect or with redux-mock-store (or with me)
I created a simplified version of my problem on CodeSandbox: https://codesandbox.io/s/wizardly-wave-nkuvw?file=/src/Component.js
Here is the problem:
I have a component (Component.js) which uses createSelector to get a value from the store:
To test this component I created 2 different tests (Component.test.js) in which I use react-mock-store to mock my store.
Case 1: Mock item with ID 1 and value 1
Case 2: Mock item with ID 1 and value 2
When I create a store by calling mockStore with these items directly everything works as expected.
Case 1 returns value 1 and Case 2 returns value 2 👍
Now, in my real app I have other parts of my state that I have to mock so I start from a common object (initialState) and append these items to it. I recreated that here as Case 3 and 4:
Now Case 4 fails because the selector returns the value from Case 3 (value 1).
Some observations:
This last observation leads me to believe this might be an issue with Reselect.
I would appreciate some help. Thank you.
The text was updated successfully, but these errors were encountered: