thunkAPI.getState 不是函数:reduxtoolkit 和 jest 出错

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

我正在使用 createAsyncThunk 并使用 jest/ReduxToolkit/TypeScript 为其编写测试。

这是我的切片。

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;

这是我的测试。

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

当我 运行 测试时,我得到错误并且日志输出:

{ 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 } }

所以我理解错误消息 TypeError: thunkAPI.getState is not a function 指出切片中的 thunkAPI.getState() 导致了错误,但在使用 Web 浏览器 运行 时它不会导致任何错误。

有人有想法吗?谢谢。

版本

state变量的推断TS类型为:

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

您应该将 store.getState 而不是 store.getState() 传递给 state。所以应该是:

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

不是:

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

你真的应该发送它并让商店调用它而不是自己做:

    const result = await dispatch(getUsers())

所以我发现问题是类型不匹配。我必须指定 dispatch.

的类型

首先像官方文档说的那样导出 AppDispatch。

export type AppDispatch = typeof store.dispatch;

并且当你调用 dispatch 时,你需要在你的测试中显式『键入』dispatch。

let store: EnhancedStore;
let dispatch: AppDispatch;

beforeEach(() => {
store = configureStore({
    reducer: {
      // Add your reducers
    },
  });
  dispatch = store.dispatch;
});

之后,您可以调用 dispatch thunks 和 actions。只需写 dispatch([thunk/action]) 就可以了。