如何在从父组件传递的子组件中测试回调单击?

IT技术 javascript reactjs jestjs enzyme
2021-05-05 02:17:35

我有以下父组件:

import React, { Fragment } from 'react';

export class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      show: false,
    };
  }

  onClick = () => {
    // working
  }

  render() {

    return (
      <Fragment>
        <Child handleClick={this.onClick} />
      </Fragment>
    );
  }
}

我需要检查回调是否在子组件中触发,onClick 方法将在父组件中触发。我写了这样一个测试:

test("check callback fire", () => {
    let mockFn = jest.fn();
    Parent.prototype.onClick = mockFn;

    let wrapper = shallow(<Parent />);

    wrapper.find('Child').props().handleClick();

    expect(mockFn).toHaveBeenCalled();
  });

我有一个错误

 Expected mock function to have been called, but it was not called.

我怎样才能用笑话和酶正确地做到这一点?是否可以?

3个回答

您的 onClick 函数在对象本身上,而不是原型上。您必须修改对象实例。

let mockFn = jest.fn();
let wrapper = shallow(<Parent />);
wrapper.find('Child').props().handleClick = mockFn; 
wrapper.find('Child').props().handleClick(); 
expect(mockFn).toHaveBeenCalled();

话虽如此,您自己正在调用 onClick,因此测试它是否被调用是没有意义的。

您应该测试它的效果,例如,部分 DOM 没有显示。

您还可以测试他们组件的状态更新是否正确,即 {show: false}

问题来自onClick方法的声明,如果你像这样声明你的函数

onClick() {}

代替

onClick = () => {}

您的测试应该可以工作,因为onClick将存在于Parent.prototype对象中,请注意方法中的this关键字onClick将不再引用类实例。

如果您需要使用箭头函数(以获得 的正确值this),您可以修改您的测试:

test("check callback fire", () => {
  let mockFn = jest.fn();

  let wrapper = shallow(<Parent />);
  wrapper.instance().onClick = mockFn;

  wrapper.find('Child').props().handleClick();

  expect(mockFn).toHaveBeenCalled();
});

onClick = () => {}Parent类中使用不会将属性添加到Parent.prototype,实际上它会声明一个像这样的实例变量:

class Parent {
  constructor() {
    super();
    this.onClick = () => {}
  }
}

顺便说一句,Fragment你的render方法内部的存在似乎没有用,你可以删除它

render() {
  return <Child handleClick={this.onClick} />;
}

我建议通过两个测试来做到这一点:

  1. 在适当的时候调用Child断言其onClickprop组件的单元测试
  2. 一个单元测试,它在渲染时Parent正确设置了它的onClickpropsChild

通过这两个测试,如果这些部分中的任何一个失败,您都会收到警报。