无法读取未定义的 属性 'endsWith' - Redux 工具包测试

Cannot read property 'endsWith' of undefined - Redux Toolkit testing

我在使用 React 测试库测试切片时遇到问题。我是运行下面的简单测试:

import reducer from "states/slices";

test("should return the initial state", () => {
  expect(reducer(undefined, {})).toEqual({
    loading: true,
    libraries: [],
    books: [],
    error: {
      error: false,
      variant: "error",
      message: "",
    },
  });
});

被测切片如下:

import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { getLibraries, getBooks } from "api";

const initialState = {
  loading: true,
  libraries: [],
  books: [],
  error: {
    error: false,
    variant: "error",
    message: "",
  },
};

export const fetchLibraries = createAsyncThunk("books/libraries", async () => {
  const res = await getLibraries();
  return res.data;
});

export const fetchBooks = createAsyncThunk(
  "books/books",
  async ({ title, libraryId, page }) => {
    const res = await getBooks(title, libraryId, page);
    return res.data;
  }
);

const booksSlice = createSlice({
  name: "books",
  initialState,
  reducers: {
    unsetError: (state) => {
      state.error = { error: false, variant: "error", message: "" };
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchLibraries.fulfilled, (state, action) => {
        state.loading = false;
        state.libraries = action.payload;
      })
      .addCase(fetchBooks.fulfilled, (state, action) => {
        state.loading = false;
        state.books = action.payload;
      })
      // .addCase(fetchBooks.pending, (state, action) => {
      //   state.loading = true;
      //   state.error = { error: false, variant: "error", message: "" };
      // })
      // .addCase(fetchLibraries.pending, (state, action) => {
      //   state.loading = true;
      //   state.error = { error: false, variant: "error", message: "" };
      // })
      // .addCase(fetchBooks.rejected, (state, action) => {
      //   state.loading = false;
      //   state.error.error = true;
      //   state.error.variant = "error";
      //   state.error.message =
      //     "Error. Try again.";
      // })
      // .addCase(fetchLibraries.rejected, (state, action) => {
      //   state.loading = false;
      //   state.error.error = true;
      //   state.error.variant = "error";
      //   state.error.message =
      //     "Error. Try again.";
      // });
      .addMatcher(
        (action) => action.type.endsWith("/pending"),
        (state, action) => {
          state.loading = true;
          state.error = { error: false, variant: "error", message: "" };
        }
      )
      .addMatcher(
        (action) => action.type.endsWith("/rejected"),
        (state, action) => {
          state.loading = false;
          state.error.error = true;
          state.error.variant = "error";
          state.error.message =
            "Error. Try again.";
        }
      );
  },
});

const { actions, reducer } = booksSlice;

export const { unsetError } = actions;

export default reducer;

当 运行 切片中包含 addMatcher 的测试时,我将返回 TypeError: Cannot read property 'endsWith' of undefined。如果我将它们替换为 addCases(注释的),测试将按预期进行。

相反,如果我正常启动应用程序,则在任何一种情况下一切正常。

为什么会这样?我错误地定义了匹配器?

在您的测试用例中,您使用 {} 作为一个动作。因此,当您检查匹配器 action.type.endsWith() 时,未定义 action.type

如果您在匹配器中使用 action.type?.endsWith,您或许可以解决此问题。