typescript 如何使用redux-toolkit slice测试thunk?

pkwftd7m  于 2023-05-23  发布在  TypeScript
关注(0)|答案(1)|浏览(187)

我有一个简单的想法:

import { AppDispatch } from "../store";
import { Api } from "../../shared/api/index";
import { registrationFormSlice } from "../registration";

export const logIn =
  (email: string, password: string) =>
  async (dispatch: AppDispatch) => {
    try {         
      const { status } = await Api.auth.logIn({ email, password });
      if (status === 200) {
        dispatch(registrationFormSlice.actions.reset());
      }          
    } catch (error: any) {
      console.error(error);
    }
  };

我该如何测试它?
我试图自己找到答案,但我所能找到的一切都没有给予答案,或者非常难以理解。我甚至不能写我如何测试这个THUNK,因为我不知道从哪里开始。

zu0ti5jz

zu0ti5jz1#

如果你只想测试动作相关的逻辑,可以使用redux-mock-store包。
用于测试Redux异步操作创建者和中间件的模拟商店。模拟存储将创建一个分派的操作数组,用作测试的操作日志。
请注意,这个库是为了测试动作相关的逻辑而设计的,而不是reducer相关的逻辑。
例如
api.ts

const Api = {
  auth: {
    async logIn(payload) {
      return fetch('http://localhost:3000/api/login')
    }
  }
}

export { Api }

registration.ts

import { createSlice } from '@reduxjs/toolkit';

const registrationFormSlice = createSlice({
  name: 'registration',
  initialState: {},
  reducers: {
    reset() { }
  }
})

export { registrationFormSlice }

thunk.ts

import { Api } from "./api";
import { registrationFormSlice } from "./registration";

type AppDispatch = any;

export const logIn =
  (email: string, password: string) =>
    async (dispatch: AppDispatch) => {
      try {
        const { status } = await Api.auth.logIn({ email, password });
        if (status === 200) {
          dispatch(registrationFormSlice.actions.reset());
        }
      } catch (error: any) {
        console.error(error);
      }
    };

thunk.test.ts

import { AnyAction } from 'redux';
import configureStore, { MockStoreCreator } from 'redux-mock-store'
import thunk, { ThunkDispatch } from 'redux-thunk'
import { logIn } from './thunk';
import { Api } from "./api";
import { registrationFormSlice } from './registration';

type RootState = any;

const middlewares = [thunk]
type DispatchExts = ThunkDispatch<RootState, undefined, AnyAction>
const mockStoreCreator: MockStoreCreator<RootState, DispatchExts> =
  configureStore<RootState, DispatchExts>(middlewares)

describe('thunk', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  })
  test('should pass', () => {
    jest.spyOn(Api.auth, 'logIn').mockResolvedValue({ status: 200 } as unknown as Response)
    const store = mockStoreCreator();
    return store.dispatch(logIn('example@gmail.com', '123')).then(() => {
      const actions = store.getActions();
      expect(actions).toEqual([registrationFormSlice.actions.reset()])
    })
  })
})

测试结果:

PASS  stackoverflow/76302702/thunk.test.ts (19.876 s)
  thunk
    ✓ should pass (7 ms)

-----------------|---------|----------|---------|---------|-------------------
File             | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------------|---------|----------|---------|---------|-------------------
All files        |   88.24 |       50 |      60 |    87.5 |                   
 api.ts          |   66.67 |      100 |       0 |   66.67 | 4                 
 registration.ts |     100 |      100 |       0 |     100 |                   
 thunk.ts        |   90.91 |       50 |     100 |      90 | 15                
-----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        21.879 s

相关问题