Home > OS >  React/ReduxToolkit testing failed with "TypeError: Cannot read property 'pending' of
React/ReduxToolkit testing failed with "TypeError: Cannot read property 'pending' of

Time:10-13

Im currently trying to setup tests into my project which is using React and ReduxToolkit. For async actions Im using createAsyncThunk coming from @reduxjs/toolkit. Ive separated all those actions into separate file and then I import them into the file containing the "slice" to be able to use them into extraReducers like so:

import { myAsyncThunk } from './some-thunks.file.ts';

const mySlice = createSlice({
  ....blah blah,
  extraReducers: {
    [myAsyncThunk.pending.type]: state => {...},
    [myAsyncThunk.rejected.type]: state => {...},
    [myAsyncThunk.fulfilled.type]: state => {...},
  }
})

Everything is working fine with that approach without any problems, BUT I there is a problem when trying to run tests..

Ive followed the @reduxjs/toolkit docs and made a wrapper around render method of @testing-library/react like so: (*Ive also included Router provider)

import { Provider } from 'react-redux';
import { Router } from 'react-router-dom';
import { render as rtlRender } from '@testing-library/react';
import { configureStore } from '@reduxjs/toolkit';

import history from '../../history';
import { reducer } from '../store/index';

function render(ui, { preloadedState, store = configureStore({ reducer, preloadedState }), ...renderOptions } = {}) {
    function Wrapper({ children }) {
        return (
            <Provider store={store}>
                <Router history={history}>{children}</Router>
            </Provider>
        );
    }

    return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
}

export * from '@testing-library/react';

export { render };

Then Ive written ULTRA simple test like:

import { render } from '../../my-custom-render.ts';

import SigninComponent from './signin.component';

describe('SigninComponent', () => {
    const { baseElement } = render(<SigninComponent />);

    it('should render', async () => {
        expect(baseElement).toBeTruthy();
    });
});

And here the problem comes... I got the following error when trying to run the tests:

 FAIL   my-application  ...path-to-component/signin/signin.component.spec.tsxTest suite failed to run

    TypeError: Cannot read property 'pending' of undefined

      86 |  },
      87 |  extraReducers: {
    > 88 |      [getOrdersList.pending.type]: state => {
         |                     ^
      89 |          state.isLoading = true;
      90 |      },
      91 |      [getOrdersList.rejected.type]: state => {

      at Object.<anonymous> (src/app/store/features/orders/orders.slice.ts:88:18)
      at Object.<anonymous> (src/app/store/features/actions.export.ts:3:1)
      at Object.<anonymous> (src/app/store/features/orders/orders.async.ts:14:1)
      at Object.<anonymous> (src/app/store/features/apiRoot/apiRoot.slice.ts:17:1)
      at Object.<anonymous> (src/app/store/index.ts:3:1)
      at Object.<anonymous> (src/app/utils/table.util.tsx:5:1)
      at Object.<anonymous> (src/app/utils/_index.ts:3:1)
      at Object.<anonymous> (src/app/routes/auth/signin/signin.component.spec.tsx:1:1)
      at TestScheduler.scheduleTests (../../node_modules/@jest/core/build/TestScheduler.js:333:13)
      at runJest (../../node_modules/@jest/core/build/runJest.js:387:19)
      at _run10000 (../../node_modules/@jest/core/build/cli/index.js:408:7)
      at Object.runCLI (../../node_modules/@jest/core/build/cli/index.js:261:3)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        8.615 s
Ran all test suites.

I found that if the async thunk is NOT into separate file but its in the same file as the slice (*not just imported there), everything is working and the test passes. (*My application is already pretty big, so for me its not an option to move all async thunks into the same file as the slice is) Also another problem is that the "problematic" async thunk isn't actually part of the component that Im trying to test. Its from completely different module, but I assume thats, because Im passing my whole state to the provider when wrapping the render.

So I hope Ive describe my problem good enough to understand and would be really thankful if someone have an idea how to solve that issue!

Thanks in advance!

CodePudding user response:

Since this was asked and answered over in https://github.com/reduxjs/redux-toolkit/issues/1609 as well, I'll paste the answer here for visibility:

That suggests you have a circular import problem, which is causing the imported variable to be undefined at runtime. You'll have to figure out what files are involved in the import circle, and rearrange the code to avoid that. The Webpack https://github.com/aackerman/circular-dependency-plugin can help identify which files are the issue here. See https://redux-toolkit.js.org/usage/usage-guide#exporting-and-using-slices for some suggestions on rearranging the logic.

As a side note, we recommend using the "builder callback" syntax for extraReducers rather than the "object lookup table" form:

https://redux-toolkit.js.org/api/createSlice#the-extrareducers-builder-callback-notation

  • Related