javascript - 使用 redux 操作创建器调用 onClick() 时应该测试什么?

标签 javascript reactjs jestjs enzyme

我正在尝试测试一个简单的复选框输入组件,该组件在其 onChange 方法中触发一个操作来保存复选框的值(True 或 False)。该组件如下:

import React, {Component} from 'react';
import uuid from 'uuid/v1';
import './styles.css';
import { connect } from 'react-redux';
import { saveCheckboxInput } from '../../actions/userInputActions';

class CheckboxSingle extends Component {

  constructor () {
    super();
    this.onChange = this.onChange.bind(this);
    this.state = {
      id : uuid(), // generate a unique id
    }
  }

  onChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    this.props.saveCheckboxInput(this.props.linkId, value, this.props.desc, this.props.relatedLinkIds, this.props.stepNumber);
  }

  render(){
    return(
      <div className="col-sm-12 no-padding-left">
        <label className="checkbox-container label-text">{this.props.desc}
          <input id={this.state.id} type="checkbox" name="checkBoxValue" checked={this.props.isChecked}
      onChange={(e) => this.onChange(e)}/>
          <span className="checkmark"></span>
        </label>
      </div>
    )
  }
}

function mapStateToProps(state, ownProps) {
  // Tie checkBoxValue to store answer
  // Get answers in the context of checkbox (determines if checked or not)
  var stepAnswers = state.userInputState.stepResponses[ownProps.stepNumber];
  var isCheckedValue = null;
  // Note: only functional w/ one checkbox input in flow
  // TODO: make functional for multiple checkbox inputs in flow
  for(var i=0; i < stepAnswers.length; i++) {
    if(stepAnswers[i].type === "questionnaire-checkbox-input") {
      isCheckedValue = stepAnswers[i].value;
    }
  }
  return {
    isChecked : isCheckedValue
  };
}



export default connect(
  mapStateToProps,
  { saveCheckboxInput },
 )(CheckboxSingle);

通过下面的测试来模拟 onChange() 函数:

describe('CheckboxSingle', () => {

  const initialState = {
    userInputState: {
       stepResponses: [
        {},
        {
          type: "questionnaire-checkbox-input",
          name: "mockLinkId",
          value: false,
          prefixText: "mockDesc",
          relatedLinkIds: ["mock1", "mock2"]
        }
      ]
    }
  }
  const mockStore = configureStore()
  let store, shallowWrapper, dispatch

  beforeEach(() => {
    store = mockStore(initialState)
    dispatch = jest.fn();
    shallowWrapper = shallow(<CheckboxSingle store={store} dispatch={dispatch} desc="mockDesc"
  linkId="mockLinkId" relatedLinkIds={["mock1", "mock2"]} stepNumber={1} />).dive()
  });    

  // TODO: test action creator firing upon click
  test('should call onChange after clicked', () => {
    const onChangeFake = jest.spyOn(shallowWrapper.instance(), 'onChange');
    shallowWrapper.find('input[type="checkbox"]').simulate('change', { target: { checked: true } });
    expect(onChangeFake).toHaveBeenCalledTimes(1);
  });

});

测试组件更改时触发 this.props.saveCheckboxInput 的最佳方法是什么(类似于模拟更改测试)? enzyme 新手,因此任何见解将不胜感激!

最佳答案

首先 onChange={(e) => this.onChange(e)} 是一种不好的做法,因为它会为组件的每个渲染创建一个新函数,您可以简单地写入onChange={this.onChange}

然后要测试 prop saveCheckboxInput 是否已被调用,您只需检查是否已使用与创建的操作相对应的参数调用了商店的 dispatch 函数通过原始的 saveCheckboxInput 函数

import { saveCheckboxInput } from '../../actions/userInputActions';

let store, shallowWrapper;

beforeEach(() => {
    store = mockStore(initialState)
    store.dispatch = jest.fn();
    shallowWrapper = shallow(
        <CheckboxSingle 
            store={store} 
            desc="mockDesc"
            linkId="mockLinkId" 
            relatedLinkIds={["mock1", "mock2"]} 
            stepNumber={1} 
        />
    ).dive();
}); 

test('should call onChange after clicked', () => {
    const action = saveCheckboxInput(
        "mockLinkId", 
        true, 
        "mockDesc", 
        ["mock1", "mock2"], 
        1
    );

    shallowWrapper.find('input[type="checkbox"]')
        .simulate('change', { target: { checked: true } });
    expect(store.dispatch).toHaveBeenCalledWith(action);
});

关于javascript - 使用 redux 操作创建器调用 onClick() 时应该测试什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52208973/

相关文章:

reactjs - Jest——编写测试描述的正确方法

javascript - TypeScript 装饰器中的异步调用

unit-testing - Jest 进行 React 快照测试 - 失败的 Prop 类型 : Invalid prop `children` of type `string` supplied

javascript - React JS 中通过 id 链接

reactjs - @urql/exchange-auth 不在 header 中发送 token

javascript - 如果在更新下拉菜单时网络服务不可用怎么办?

javascript - 为什么必须使用关键字 "this"而不是类名?

javascript - 如何让鼠标事件在被另一个元素遮挡的元素上触发?

javascript - AngularFire firestore get/snapshotchanges/valuechanges 对 observable 的操作不是异步的?

javascript - 如果我的组件作为 React JS 中的子 Prop 传递给布局组件,如何访问布局组件中的 Prop ?