Redux模拟存储在使用Jest/RTL的React测试环境中未更新。

huangapple go评论62阅读模式
英文:

Redux mock store is not being updated on react test environment using Jest/RTL

问题

以下是翻译好的代码部分:

I'm new on testing and I'm trying to implement a unit test to check if a counter is being correctly updated after a button is clicked. Everything works fine on dev and production environments, so I'm pretty sure it has the correct behavior, but on the test environment, I couldn't figure out how to make it work so far.

My code is too big and complex to put it all here, but this is my test setup:

import { render, screen, fireEvent, act } from '@testing-library/react';
import { Provider } from 'react-redux'
import configureStore from 'redux-mock-store';
import ProductsListQtde from './ProductsListQtde';
import * as useInitProductsModule from 'hooks/useInitProducts';
import { ProductsList } from 'common/types';

const mockStore = configureStore([]);
const initialState = {
   productsDataState: [
      { 
         id: 1,
         nome: "Produto 1",
         qtde: 2,
         valor: 10,
         valorTotal: 20
      },
      { 
         id: 2,
         nome: "Produto 2",
         qtde: 5,
         valor: 20,
         valorTotal: 60
      },
  ],
};
const storeMock = mockStore(initialState);

describe('quantity component', () => {
  test('plus button is clicked the quantity is incremented by 1', async () => {
    const id = 1;
    const mockedInitProducts = jest.fn();

    jest.spyOn(useInitProductsModule, 'default').mockReturnValue({
      initProducts: mockedInitProducts,
    });

   const { container } = render(
      <Provider store={storeMock}>
        <ProductsListQtde qtde={2} id={id} />
      </Provider>
    );

    const plusButton = screen.getByLabelText('plus');

    fireEvent.click(plusButton);

   const updatedQtdeValues = [
      { 
         id: 1,
         nome: "Produto 1",
         qtde: 3,
         valor: 10,
         valorTotal: 30
      },
      { 
         id: 2,
         nome: "Produto 2",
         qtde: 5,
         valor: 20,
         valorTotal: 60
      },
   ]

    expect(mockedInitProducts).toHaveBeenCalledTimes(1);
    expect(mockedInitProducts).toHaveBeenCalledWith('updQtde', updatedQtdeValues);

    const updatedState = storeMock.getState().productsDataState;
    const updatedQtde = updatedState.find((product: ProductsList) => product.id === id)?.qtde;

    expect(updatedQtde).toBe(3);
  });
});

请注意,这只是代码的翻译,不包括问题的回答。如果您有任何其他疑问或需要进一步的帮助,请随时提出。

英文:

I'm new on testing and I'm trying to implement a unit test to check if a counter is being correctly updated after a button is clicked. Everything works fine on dev and production environments, so I'm pretty sure it has the correct behavior, but on test environment I couldn't figure out how to make it work so far.

My code is too big and complex to put it all here, but this is my test setup:

import { render, screen, fireEvent, act } from &#39;@testing-library/react&#39;;
import { Provider } from &#39;react-redux&#39;
import configureStore from &#39;redux-mock-store&#39;;
import ProductsListQtde from &#39;./ProductsListQtde&#39;;
import * as useInitProductsModule from &#39;hooks/useInitProducts&#39;;
import { ProductsList } from &#39;common/types&#39;;
const mockStore = configureStore([]);
const initialState = {
productsDataState: [
{ 
id: 1,
nome: &quot;Produto 1&quot;,
qtde: 2,
valor: 10,
valorTotal: 20
},
{ 
id: 2,
nome: &quot;Produto 2&quot;,
qtde: 5,
valor: 20,
valorTotal: 60
},
],
};
const storeMock = mockStore(initialState);
describe(&#39;quantity component&#39;, () =&gt; {
test(&#39;plus button is clicked the quantity is incremented by 1&#39;, async () =&gt; {
const id = 1;
const mockedInitProducts = jest.fn();
jest.spyOn(useInitProductsModule, &#39;default&#39;).mockReturnValue({
initProducts: mockedInitProducts,
});
const { container } = render(
&lt;Provider store={storeMock}&gt;
&lt;ProductsListQtde qtde={2} id={id} /&gt;
&lt;/Provider&gt;
);
const plusButton = screen.getByLabelText(&#39;plus&#39;);
fireEvent.click(plusButton);
const updatedQtdeValues = [
{ 
id: 1,
nome: &quot;Produto 1&quot;,
qtde: 3,
valor: 10,
valorTotal: 30
},
{ 
id: 2,
nome: &quot;Produto 2&quot;,
qtde: 5,
valor: 20,
valorTotal: 60
},
]
expect(mockedInitProducts).toHaveBeenCalledTimes(1);
expect(mockedInitProducts).toHaveBeenCalledWith(&#39;updQtde&#39;, updatedQtdeValues);
const updatedState = storeMock.getState().productsDataState;
const updatedQtde = updatedState.find((product: ProductsList) =&gt; product.id === id)?.qtde;
expect(updatedQtde).toBe(3);
});
});

Every assertion passes but the last one, the function is being called with the correct values, but the store is not being updated. qtde property starts as 2 and should be updated to 3.

Is there anything wrong with my approach or am I missing something?

I'm not using react toolkit, this is an old project and I'm implementing tests on it only for educational purposes.

Please, let me know if I need to add more information to make it clearer.

答案1

得分: 1

redux-mock-store文档中:

请注意,该库旨在测试与操作相关的逻辑,而不是与 reducer 相关的逻辑。换句话说,它不会更新 Redux 存储。

查看redux-mock-store包的getState()方法,传递给mockStore函数的状态对象将不经过任何操作而返回。

在测试 Redux 动作和 reducer 时,您有一些选择。

英文:

From redux-mock-store doc:

> Please note that this library is designed to test the action-related logic, not the reducer-related one. In other words, it does not update the Redux store.

Take a look at getState() method of redux-mock-store package, the state object passed in mockStore function is returned without any operations.

You have some choices for testing redux actions and reducers.

huangapple
  • 本文由 发表于 2023年6月5日 06:27:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76402653.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定