javascript - 在 React 中测试 Actions、Reducers 和上下文

标签 javascript reactjs jestjs react-context react-testing-library

我使用 Hooks 和 Context 构建了多个 React 功能组件。一切正常。现在我需要为所有内容编写测试。我对如何与其中一些人一起前进感到困惑,因此想接触社区。

操作 以下是我的一个操作文件的示例:

export const ADD_VEHICLE: 'ADD_VEHICLE' = 'ADD_VEHICLE';
export const UPDATE_VEHICLE: 'UPDATE_VEHICLE' = 'UPDATE_VEHICLE';

type AddVehicleAction = {type: typeof ADD_VEHICLE, isDirty: boolean};
type UpdateVehicleAction = {type: typeof UPDATE_VEHICLE, id: number, propName: string, payload: string | number};

export type VehiclesActions = 
     | AddVehicleAction
     | UpdateVehicleAction;

我应该如何测试这个 Actions 文件?我的意思不是与其他任何东西结合在一起,我的意思是它并且只是它? 从评论来看,我似乎同意此文件中没有任何内容可以直接测试。

reducer 我的每个Reducers 文件都直接连接到并支持特定的上下文。以下是我的一个Reducers 文件的示例:

import type { VehiclesState } from '../VehiclesContext';
import type { VehiclesActions } from '../actions/Vehicles';
import type { Vehicle } from '../SharedTypes';

import { ADD_VEHICLE,
         UPDATE_VEHICLE
       } from '../actions/Vehicles';

export const vehiclesReducer = (state: VehiclesState, action: VehiclesActions) => {
  switch (action.type) {

  case ADD_VEHICLE: {
    const length = state.vehicles.length;
    const newId = (length === 0) ? 0 : state.vehicles[length - 1].id + 1;
    const newVehicle = {
      id: newId,
      vin: '',
      license: ''
    };

    return {
      ...state,
      vehicles: [...state.vehicles, newVehicle],
      isDirty: action.isDirty
    };
  }

  case UPDATE_VEHICLE: {
    return {
      ...state,
      vehicles: state.vehicles.map((vehicle: Vehicle) => {
        if (vehicle.id === action.id) {
          return {
            ...vehicle,
            [action.propName]: action.payload
          };
        } else {
          return vehicle;
        }
      }),
      isDirty: true
    };
  }

如果您想仅为这个Reducers 文件构建测试,您会使用什么方法?我的想法是像这样渲染 DOM:

function CustomComponent() {
  const vehiclesState = useVehiclesState();
  const { isDirty,
          companyId,
          vehicles 
        } = vehiclesState;  
  const dispatch = useVehiclesDispatch();

  return null;
}

function renderDom() {
  return {
    ...render(
      <VehiclesProvider>
        <CustomComponent />
      </VehiclesProvider>
    )  
  };
}

虽然上面的代码确实可以运行,但我现在遇到的问题是 vehiclesStatedispatch在我的测试代码中无法访问,因此我试图弄清楚如何在每个 describe / it 中“显示”这些内容构造。如有任何建议,我们将不胜感激。

上下文 我的上下文遵循 Kent C. Dodds 概述的相同模式:https://kentcdodds.com/blog/how-to-use-react-context-effectively - StateContext 和 DispatchContext 是分开的,并且有一个默认状态。考虑到这个代码模式,并且考虑到我已经有了一个针对 Context 的 Reducers 的单独测试文件,那么具体可以只针对 Context 测试什么?

最佳答案

与我的评论相同,我真的认为你应该阅读 redux docs for writing tests这样您就可以大致了解要做什么。

但是由于您已经有了一个 reducer ,因此您希望编写测试用例以遵循此模式

  1. 每个操作至少有 1 次测试
  2. 每个测试都会有一个“先前的状态”,该状态将会改变
  3. 您将调用您的 reducer ,传递操作和之前的状态
  4. 您将断言您的新状态与预期相同

这是一个代码示例:

it('adds a new car when there are no cars yet', () => {
  // you want to put here values that WILL change, so that you don't risk
  // a false positive in your unit test
  const previousState = {
    vehicles: [],
    isDirty: false,
  };

  const state = reducer(previousState, { type: ADD_VEHICLE });

  expect(state).toEqual({
    vehicles: [{
      id: 1,
      vin: '',
      license: '',
    }],
    isDirty: true,
  });
});

it('adds a new car when there are existing cars already, () => {
  // ...
});

我还建议使用操作创建器而不是直接创建操作对象,因为它更具可读性:

// actions.js
export const addVehicle = () => ({
  type: ADD_VEHICLE
})

// reducer.test.js
it('adds a new car when there are no cars yet', () => {
  //...
  const state = reducer(previousState, actions.addVehicle());

关于javascript - 在 React 中测试 Actions、Reducers 和上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59038176/

相关文章:

javascript - 将 props 传递给 createSwitchNavigator 会破坏 createAppContainer

javascript - Sweet Alert没有显示动态值,我做错了什么?

reactjs - 如何查找不同元素的 getByRole 可用的属性?

javascript - 如何在ajax中插入数组?

javascript - 不使用 jquery 获取带有类名的下一个元素

javascript - react : Inline if doesn't resolve to false when value is 'undefined'

javascript - Jest- JSDOM 在实例化 JSDOM 时将 HTML 传递给 Jest 中的 JSDOM 构造函数

jestjs - 如何配置 jest 使用的 jsdom 实例?

javascript - 如何从其他组件的事件监听器($on)调用此组件方法?

javascript - 未捕获( promise 中)TypeError : _this2. context.router.push 不是函数