首页 > 解决方案 > 打字稿减速器单元测试

问题描述

我有以下单元测试:

it('should handle REPAIRS_PROPERTY_LOAD_SUCCESS', () => {
  const result = reducer(initialState, {type: 'repairs/PROPERTY_PAGE_LOAD_SUCCESS'})
  expect(result).toEqual({}); /* the test would fail */
})

但出现以下错误:

[ts] Argument of type '{ type: "repairs/PROPERTY_PAGE_LOAD_SUCCESS"; }' is not assignable to parameter of type 'RepairsAction'. Type '{ type: "repairs/PROPERTY_PAGE_LOAD_SUCCESS"; }' is not assignable to type 'RepairsPropertyLoadSuccessAction'. Property 'payload' is missing in type '{ type: "repairs/PROPERTY_PAGE_LOAD_SUCCESS"; }'.

我的减速器文件如下:

...
/* Actions & action types */
const REPAIRS_PROPERTY_LOAD = 'repairs/PROPERTY_PAGE_LOAD'
const REPAIRS_PROPERTY_LOAD_SUCCESS = 'repairs/PROPERTY_PAGE_LOAD_SUCCESS'
const REPAIRS_SEARCH = 'repairs/REPAIRS_SEARCH'
const REPAIRS_SEARCH_SUCCESS = 'repairs/REPAIRS_SEARCH_SUCCESS'

type RepairsPropertyLoadAction = {
  type: typeof REPAIRS_PROPERTY_LOAD
}

export type RepairsPropertyLoadSuccessAction = {
  type: typeof REPAIRS_PROPERTY_LOAD_SUCCESS
  payload: RepairsProperty
}

type RepairsSearchAction = {
  type: typeof REPAIRS_SEARCH
}

type RepairsSearchSuccessAction = {
  type: typeof REPAIRS_SEARCH_SUCCESS
  payload: RepairsProperty
}

export type RepairsAction =
  | RepairsPropertyLoadAction
  | RepairsPropertyLoadSuccessAction
  | RepairsSearchAction
  | RepairsSearchSuccessAction

/* Reducer */
export type RepairsState = {
  data: Property[]
  isFetching: boolean
}

export const initialState: RepairsState = {
  data: [
    {
      id: '',
      jobNo: '',
      trade: '',
      priority: '',
      status: '',
      raisedDate: '',
      appointmentDate: '',
      completedDate: '',
      description: '',
    },
  ],
  isFetching: false,
}

export default function reducer(state = initialState, action: RepairsAction): RepairsState {
  switch (action.type) {
    case REPAIRS_PROPERTY_LOAD:
    case REPAIRS_SEARCH: {
      return {
        ...state,
        isFetching: true,
      }
    }
    case REPAIRS_PROPERTY_LOAD_SUCCESS:
    case REPAIRS_SEARCH_SUCCESS: {
      return {
        ...state,
        isFetching: false,
        data: action.payload.models,
      }
    }
    default:
      return state
  }
}
...

与 repairsProperty 为:

...
export default class Property {
  id: string = ''
  jobNo: string = ''
  trade: string = ''
  priority: string = ''
  status: string = ''
  raisedDate: string = ''
  appointmentDate: string = ''
  completedDate: string = ''
  description: string = ''
}

export class RepairsProperty {
  models: Property[] = []
}
...

标签: javascripttypescriptredux

解决方案


您的减速器已键入,并且您在测试减速器时没有指定操作“REPAIRS_PROPERTY_LOAD_SUCCESS”所需的有效负载。当您使用可区分的联合类型时,您需要确保您传递给减速器的操作将匹配指定的类型之一。

看:

export type RepairsAction =
  | RepairsPropertyLoadAction
  | RepairsPropertyLoadSuccessAction /* <--- Matches this Type */
  | RepairsSearchAction
  | RepairsSearchSuccessAction

export type RepairsPropertyLoadSuccessAction = {
  type: typeof REPAIRS_PROPERTY_LOAD_SUCCESS
  payload: RepairsProperty /* <--- Your payload type is specified here */
}

// Need to make sure that your test action payload conforms to this
// type as the payload when you're dispatching the
// "RepairsPropertyLoadSuccessAction" action
export class RepairsProperty {
  models: Property[] = []
}

所以你的测试应该是:

it("should handle REPAIRS_PROPERTY_LOAD_SUCCESS", () => {
  const result = reducer(initialState, {
    type: "repairs/PROPERTY_PAGE_LOAD_SUCCESS",
    payload: {
        models: [],
    } /* A type that conforms to the RepairsProperty type */
  });
  expect(result).not.toEqual({});
});


推荐阅读