Search code examples
typescriptreduxjestjsredux-toolkit

thunkAPI.getState is not a function: Error with reduxtoolkit and jest


I'm using createAsyncThunk and writing a test for it with jest/ReduxToolkit/TypeScript.

This is my slice.

export const getUsers = createAsyncThunk<object[], undefined, { state: RootState }>(
  'user/getUsers',
  (_: undefined, thunkAPI) => {
    const { users } = thunkAPI.getState().user;
    if (!users) {
      // fetch users
    }
    return users;
  },
);

const userSlice = createSlice({
  name: 'user',
  initialState: {
    users: [],
  },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(getUsers.fulfilled, (state, action) => {
        state.users = action.payload;
      });
  },
});

export default userSlice;

This is my test.

let store: EnhancedStore;

beforeEach(() => {
  store = configureStore({
    reducer: {
      user: userSlice.reducer,
    },
  });
});

describe('userSlice', () => {
  test('getUsers success', async () => {
    const state = await getUsers();
    const result = await state(store.dispatch, store.getState(), undefined);
    console.log(result)
    expect(result.type).toBe('user/getUsers/fulfilled');
    expect(result.meta.requestStatus).toBe('fulfilled');
  });
});

When I run the test, I get the error and the log outputs:

{ type: 'user/getUsers/rejected', payload: undefined, meta: { arg: undefined, requestId: '***************', rejectedWithValue: false, requestStatus: 'rejected', aborted: false, condition: false }, error: { name: 'TypeError', message: 'thunkAPI.getState is not a function', stack: 'TypeError: thunkAPI.getState is not a function\n' + // omitted } }

So I understand the error message TypeError: thunkAPI.getState is not a function states the thunkAPI.getState() in the slice causes the error but it doesn't cause any error while running it with a web browser.

Does anyone have an idea? Thank you.

Versions

  • react-redux v7.2.5
  • reduxjs/toolkit v1.6.1
  • jest v27.0.6
  • ts-jest v27.0.5

Solution

  • The inferred TS type of state variable is:

    const state: (dispatch: ThunkDispatch<any, unknown, AnyAction>, getState: () => any, extra: unknown) => Promise<PayloadAction<object[], string, {
        arg: undefined;
        requestId: string;
        requestStatus: "fulfilled";
    }, never> | PayloadAction<...>> & {
        ...;
    }
    

    You should pass the store.getState rather than store.getState() to state. So it should be:

    const result = await state(store.dispatch, store.getState, undefined);
    

    NOT:

    const result = await state(store.dispatch, store.getState(), undefined);