即使我可以监视其他方法,也无法监视事件处理程序

IT技术 javascript reactjs event-handling jasmine jestjs
2021-05-22 01:47:34

我想在 React 中使用 Jest/Jasmine/Enzyme 测试事件处理程序。

我的组件.js

import React from 'react';
class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.clickHandler = this.clickHandler.bind(this);
        this.otherMethod  = this.otherMethod .bind(this);
    }

    clickHandler() { this.otherMethod(); }
    otherMethod() {}

    render() { return <div onClick={this.clickHandler}/>; }
}
export default MyComponent;

MyComponent.test.js :

import React from 'react';
import {mount} from 'enzyme';
import MyComponent from './MyComponent';

it('should work', () => {
    const componentWrapper = mount(<MyComponent/>);
    const component = componentWrapper.get(0);

    spyOn(component, 'otherMethod' ).and.callThrough();
    spyOn(component, 'clickHandler').and.callThrough();

    componentWrapper.find('div').simulate('click');

    expect(component.otherMethod ).toHaveBeenCalled(); // works
    expect(component.clickHandler).toHaveBeenCalled(); // does not work
});

尽管我认为我在监视这两个组件方法是相同的,但其中一个 (for otherMethod) 有效而另一个 (for clickHandler) 无效。我显然是在打电话,clickHandler因为otherMethod如果我没有打电话,我就不会打电话,但toHaveBeenCalled不会以clickHandler某种方式接听。为什么?

我明白,我真的没有为使用.bind(this).and.callThrough()otherMethod,但我同时使用只是这两种方法同样对待,并使用它们otherMethod不应该实际上任何区别。

另一个 SO 答案指出,在将函数附加为侦听器之前,我必须对其进行监视。如果这是我的问题,那么我不知道如何解决它:spyOn语法需要该方法是(component在这种情况下)的属性的对象,但使用component需要事先安装,MyComponent这迫使我首先附加侦听器。

我的代码使用 React(因此我将其reactjs作为问题标签包含在内可能是相关的,但不知何故我对此表示怀疑。

1个回答

对于此类测试,常见的路径是在组件实例上调用处理程序方法,而不是模拟事件。

你可以确定这个onClickprop 是由 React 团队测试的,你可以检查的是当“他们”调用你的处理程序时会发生什么。

这也允许您使用浅渲染,至少对我来说要快得多。您可以使用instance()包装器中方法轻松获取对实例的引用,然后您可以调用处理程序并监视您想要的任何内容。

const wrapper = mount(<MyComponent />)
const instance = wrapper.instance()
instance.clickHandler()
//assert whatever

事实上,可能将您的间谍附加到实例的方法(已绑定)也可以解决问题。:)

http://airbnb.io/enzyme/docs/api/ReactWrapper/instance.html

希望能帮助到你!