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

时间:2019-05-09 20:31:32

标签: javascript reactjs jestjs enzyme

我具有以下父组件:

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 个答案:

答案 0 :(得分:1)

您的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}

答案 1 :(得分:1)

问题来自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} />;
}

答案 2 :(得分:0)

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

  1. 在适当的情况下,将对断言其Child属性的onClick组件进行单元测试。
  2. Parent的单元测试,以使其在呈现时正确设置其onClick的{​​{1}}道具。

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