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

时间:2017-02-03 03:45:41

标签: javascript reactjs event-handling jasmine jestjs

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

MyComponent.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
});

尽管我认为我同时监视两个组件方法,但其中一个(对于otherMethod)有效,而另一个(对于clickHandler)却没有。我明确打电话给clickHandler otherMethod,如果我不是,toHaveBeenCalled将被调用,但clickHandler未被选中以某种方式获得.bind(this)。为什么呢?

我知道我不必在.and.callThrough()上使用otherMethodotherMethod,但我同时使用这两种方法同样对待这两种方法并在{上使用它们{1}}实际上不应该有任何区别。

This other SO answer表示我必须在将其作为侦听器附加之前监视函数。如果这是我的问题,那么我就不知道如何解决它:spyOn语法要求对象该方法是(component在这种情况下)的属性,但使用{{1需要事先安装component,这迫使我首先附加监听器。

我的代码使用React可能是相关的(因此我将MyComponent包含为问号)但不知何故我对此表示怀疑。

1 个答案:

答案 0 :(得分:2)

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

您可以确定React团队正在测试onClick道具,您可以检查“他们”调用您的处理程序时会发生什么。

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

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

事实上,可能将你的间谍附加到实例的方法(已经被绑定)也可以。 :)

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

希望它有所帮助!