Skip to content

reducer not getting called on dispatch in - redux + thunk + react testing library + MSW  #1975

@nitinmagdumvista

Description

@nitinmagdumvista

What version of React, ReactDOM/React Native, Redux, and React Redux are you using?

"react": "^17.0.1",
"react-redux": "^7.2.2",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",

What is the current behavior?

I am rendering a component with initial state using react testing custom render method which is wrapped using redux provider and router once the component is rendered on did mount its calling action creator which will fetch data from API and on success dispatch action which will update store

i am mocking API call using MSW its getting called but after that the dispatch function not updating store

=============== testRender file

import React, { ReactElement } from "react";
import {
  render as rtlRender,
  RenderOptions,
  RenderResult,
} from "@testing-library/react";
import { applyMiddleware, compose, createStore, PreloadedState } from "redux";
import { Provider } from "react-redux";
import reducers from "../../reducers/userReducer";
import { RootState } from "../../reducers";
import { Router } from "react-router-dom";
import { createMemoryHistory, MemoryHistory } from "history";
import thunk from "redux-thunk";

type CustomRenderOptions = {
  preloadedState?: PreloadedState<RootState>;
  routeHistory?: Array<string>;
  initialRouteIndex?: number;
  renderOptions?: Omit<RenderOptions, "wrapper">;
};

type customRenderRsult = RenderResult & { history: MemoryHistory };
const testRender = (
  ui: ReactElement,
  {
    preloadedState = {}, //initial state
    routeHistory, // routes till now we visited
    initialRouteIndex, // where in the history to start
    ...renderOptions
  }: CustomRenderOptions = {}
): customRenderRsult => {
  //const store = createStore(reducers, preloadedState);
  const store = compose(applyMiddleware(thunk)(createStore))(
    reducers,
    preloadedState
  );
  const history = createMemoryHistory({
    initialEntries: routeHistory, // by default "/" home page
    initialIndex: initialRouteIndex, // last element in the route history
  });
  const Wrapper: React.FC = ({ children }) => {
    return (
      <Provider store={store}>
        <Router history={history}>{children}</Router>
      </Provider>
    );
  };
  const rtlRenderObject = rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
  return { ...rtlRenderObject, history };
};

//export default renderConnected;
export * from "@testing-library/react";
export { testRender as render };

============= testIndustry file

test("rendering industry component with empty list", () => {
  server.use(
    rest.get(
      "${API_ROOT}${API_VERSION_V2}/industries",
      (req, res, ctx) => {
        return res(
          ctx.status(200),
          ctx.json({
            limit: 1,
            offset: 1,
            total: 1683,
            links: {
              base: "/v1/industries/?limit=1",
              self: "/v1/industries/?limit=1&offset=1",
              next: "/v1/industries/?limit=1&offset=2",
            },
            message: "Industry details",
            result: [
              {
                id: "5fe2cbee1a5241716ab5bff0",
                name: "tobacco exporter",
                version: 10,
                slug: "tobacco-exporter",
                tags: [
                  {
                    score: 1,
                    tag_details: {
                      id: "6037ab5d81cd0f9227662989",
                      name: "tobacco",
                    },
                  },
                  {
                    score: 5,
                    tag_details: {
                      id: "6037ac4481cd0f9227665c28",
                      name: "cigarette",
                    },
                  },
                ],
                is_verified: false,
                avgScore: 4,
                created_at: "2020-12-23T04:47:45.664Z",
                created_by: "system",
                modified_at: "2022-03-01T19:14:05.802Z",
                last_modified_by: "XoV75MMoFplzO7iGRpSZ231MCmkxnXMo@clients",
              },
            ],
          })
        );
      }
    )
  );
  const { container } = render(<Industries />, {
    preloadedState: {
      industryReducer: {
        industries: [],
        totalIndustries: 0,
      },
    },
  });

================== action creator getAllIndustries

export function getAllIndustries(payload: payload) {
  const aConfig: AxiosRequestConfig = {
    headers: {
      "content-type": "application/json",
      Authorization:
        "Bearer e,
    },
  };
  const requestUrl = `${API_ROOT}${API_VERSION_V2}/industries`;
  
  Object.assign(aConfig, { params: payload });
  return async (dispatch: any) => {
    try {
      const response = await axios.get(requestUrl, aConfig);
      **console.log("Before dispatch", response.data);**
      dispatch({
        type: actionType.INDUSTRIES,
        payload: response.data,
      });
      **console.log("After Dispatch");**
    } catch (err) {
      console.log("error", err);
      handleError(err);
    }
  };
}

============= industryReducer file

import * as actionType from "../components/common/constants";

const INITIAL_STATE = {
  industries: [],
  totalIndustries: -1,
};

const industryReducer = (state: any = INITIAL_STATE, action: any) => {
  switch (action.type) {
    
    case actionType.INDUSTRIES:
      **console.log("inside reducer", action.payload.result);**
      return {
        ...state,
        industries: action.payload.result,
        totalIndustries: action.payload.total,
      };
    default:
      return state;
  }
};

export default industryReducer;

========What is the expected behavior?

once the mocked API call data get dispatched and store get updated the new dom with that data i want to asset

but the reducer is not getting called in action creator file

     console.log("Before dispatch", response.data);
      dispatch({
        type: actionType.INDUSTRIES,
        payload: response.data,
      });
      console.log("After Dispatch");

Here both logs are getting printed Before dispatch and After Dispatch but log in industry reducer is not printing means its not getting called

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions