Search code examples
reactjsunit-testingreduxjestjsreact-testing-library

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 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);
  });
});

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.


Solution

  • 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.