I know it may seem duplicate, but I find the previous answers outdated.

Before diving into the code, let me explain what I am doing.

I'm having a login page. After clicking of the login button, I'm dispatching an action (by sending a request to the server) and handle the result (if the login is successful I'm redirecting to another page, otherwise showing an error message).

The functionality works flawlessly, but I'm getting the follwing error when I am simulating the login, by clicking the login button, whithin my unit test.

"Actions must be plain objects. Use custom middleware for async actions."

Since I am using the latest version of all packages at this time, thunk is no logger added as middleware.

This is how my configureStore looks like:

configureStore.js

// ... persistedReducer and the rest of the code should not be relevant, however I can provide it
export const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
});

login.component.js

//...
  const handleSubmit = (event) => {
    const form = event.currentTarget;
    if (form.checkValidity() === false) {
      event.stopPropagation();
    }

    setValidated(true);
    event.preventDefault();

    setLoading(true);
//here occurs the problem when the unit test is running
    dispatch(login(username, password))
      .then(() => {
        router.push("/");
        setLoading(false);
      })
      .catch(() => {
        setLoading(false);
      });
  };
 return (
    <Form
      noValidate
      validated={validated}
      onSubmit={handleSubmit}
      id="form-login"
    >
...
</Form>

and finally the unit test: login.component.test.js

//...
jest.mock("next/navigation", () => ({
  useRouter() {
    return {
      prefetch: () => null,
    };
  },
}));

describe("Login Component", () => {
let store;
beforeEach(() => {
    const mockStore = configureMockStore(/*middlewares*/); //for attempt number 3
    store = mockStore({
      auth: false,
      message: "unit-test"
    });
  });
test("it should have a working login button", async () => {
const actual = renderLoginComponent(store);
    const mockDispatch = jest.fn();
    jest.mock("react-redux", () => ({
      useSelector: jest.fn(),
      useDispatch: () => mockDispatch,
    }));
const button = actual.getByRole("button", { name: "Login" });
fireEvent.click(button);//THIS TRIGGERS THE ERROR. it is from the @testing-library/react
})
}

function renderLoginComponent(store) {
  return render(createLoginComponent(store, Login));
}

function createLoginComponent(store, ComponentToTest) {
  return (
    <Provider store={store}>
      <ComponentToTest />
    </Provider>
  );
}

I have tried:

  1. adding the tunk, as explained here

  2. mock the dispatch, as explained here

  3. passing the middleware bellow into the methdod configureMockStore() from login.component.test.js

    const defaultMiddlewareMock =    {
       serializableCheck: {
         ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
       },
     };
    

but no luck so far.

Thank you in advance for your help!

0

There are 0 best solutions below