redux toolkit test

Bin2·2022년 8월 4일
0

custom render

import React, { PropsWithChildren } from "react";
import { render as rtlRender } from "@testing-library/react";
import { Provider } from "react-redux";
import { BrowserRouter as Router } from "react-router-dom";
import setupStore, { AppStore, RootState } from "../store/store";
import type { RenderOptions } from "@testing-library/react";
import type { PreloadedState } from "@reduxjs/toolkit";

interface ExtendedRenderOptions extends Omit<RenderOptions, "queries"> {
  preloadedState?: PreloadedState<RootState>;
  store?: AppStore;
}

function render(
  ui: React.ReactElement,
  {
    preloadedState = {},
    store = setupStore(preloadedState),
    ...renderOptions
  }: ExtendedRenderOptions = {}
) {
  function Wrapper({ children }: PropsWithChildren<{}>): JSX.Element {
    return (
      <Provider store={store}>
        <Router>{children}</Router>
      </Provider>
    );
  }
  return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
}

export * from "@testing-library/react";
export { render };

reducer test

import { IUserState } from "../../interfaces";
import {
  userReducer,
  toggleSidebar,
  logoutUser,
  initialState,
} from "../../reducers/userSlice";

test("initial state를 리턴한다.", () => {
  expect(userReducer(undefined, { type: undefined })).toEqual({
    isLoading: false,
    isSidebarOpen: false,
    user: null,
  });
});

test("toggleSidebar action은 isSidebarOpen 상태를 토글 한다.", () => {
  expect(userReducer(initialState, toggleSidebar())).toEqual({
    isLoading: false,
    isSidebarOpen: true,
    user: null,
  });
});

test("logoutUser action", () => {
  const previousState: IUserState = {
    isLoading: false,
    isSidebarOpen: true,
    user: {
      email: "sangbin@gmail.com",
      lastName: "sangbin",
      location: "seoul",
      name: "sangbin",
      token: "some token",
    },
  };
  expect(userReducer(previousState, logoutUser())).toEqual({
    isLoading: false,
    isSidebarOpen: false,
    user: null,
  });
});

createAsyncThunk test

api request는 msw를 이용하여 모킹 하였다.

test("registerUser action test", async () => {
  const store = setupStore();
  const result = await store.dispatch(
    registerUser({ email: "mosangbin@gmai1l.com", password: "123" })
  );
  const response = result.payload;

  expect(response).toEqual({
    user: {
      email: "mosangbin@gmai1l.com",
      lastName: "lastName",
      location: "my city",
      name: "redux",
      token: "eyJhbGciOiJIUzI1NiIsInR",
    },
  });

  const state = store.getState().user;
  expect(state.user?.name).toBe("redux");
});

test("loginUser action test", async () => {
  const store = setupStore();
  const result = await store.dispatch(
    loginUser({ email: "sangbin@gmail.com", password: "123" })
  );
  const response = result.payload;
  expect(response).toEqual({
    user: {
      email: "testUser@test.com",
      lastName: "shake and bake",
      location: "vegan food truck",
      name: "toolkit",
      token: "eyJhbGciOiJIUzI1NiIsInR5cC",
    },
  });

  const state = store.getState().user;
  expect(state.user?.name).toBe("toolkit");
});

전역 상태의 값을 가져오는 컴포넌트를 테스트 하고 싶다면?

describe("Navbar Component", () => {
  it("user의 이름에 맞게 button의 텍스트가 변경된다.", () => {
    const state = {
      user: {
        isLoading: false,
        isSidebarOpen: false,
        user: {
          email: "asd",
          lastName: "asd",
          location: "asd",
          name: "sangbin",
          token: "asdasd",
        },
      },
    };

    render(<Navbar />, {
      preloadedState: state,
    });
    
    const button = screen.getByTestId("user-button");
    expect(button).toHaveTextContent("sangbin");
  });
profile
Developer

0개의 댓글