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

标签 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 选中。为什么?

我知道我实际上不必在 otherMethod 上使用 .bind(this).and.callThrough()但我使用这两种方法只是为了以相同的方式对待这两种方法,并且在 otherMethod 上使用它们实际上不会产生任何区别。

This other SO answer指出我必须在将函数附加为监听器之前监视该函数。如果这是我的问题,那么我不知道如何解决它: spyOn 语法需要该方法是其属性的对象(在本例中为 component ),但是使用 component 需要事先安装 MyComponent,这迫使我首先附加监听器。

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

最佳答案

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

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

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

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

事实上,可能将您的 spy 附加到实例的方法(已经绑定(bind))也可以达到目的。 :)

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

希望对你有帮助!

关于javascript - 即使我可以监视其他方法,也无法监视事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42016405/

相关文章:

javascript - 在 HTML 表单上保留从数据库接收的数据

javascript - FormData 的正确编码类型是什么?

javascript - 如何检查名称是否已存在于 Firebase 实时数据库(Firebase 和 JS)中

java - 如何将对象的事件监听器注册到其类外部的事件处理程序?

javascript - 将模拟服务注入(inject) Angular Testing 的未知问题

javascript - 单击链接时忽略表格单击功能

reactjs - 警告 : A component is changing a controlled input of type file

javascript - MUI 按钮悬停背景颜色和文本颜色

python - 在 Matplotlib 中从一组重叠的艺术家中挑选一位艺术家

c++ - 避免卡住调用回调