即使我可以侦测其他方法,也不能监视事件处理程序 [英] Can't spy on an event handler even though I can spy on other methods

查看:143
本文介绍了即使我可以侦测其他方法,也不能监视事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to test an event handler in React using Jest/Jasmine/Enzyme.

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 拾取。为什么?

In spite of the fact that I think I'm spying on the two component methods identically, one of them (for otherMethod) works while the other (for clickHandler) does not. I clearly am calling clickHandler as otherMethod wouldn't be called if I wasn't, but toHaveBeenCalled isn't being picked up for clickHandler somehow. Why?

我明白,我并不真的必须使用 .bind(this) .and.callThrough() on otherMethod 但是我只使用两个方法来相同地使用它们,并在 otherMethod 不应该有任何区别。

I understand that I don't really have to use either .bind(this) or .and.callThrough() on otherMethod but I use both just to treat the two methods identically and using them on otherMethod shouldn't actually make any difference.

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

This other SO answer states that I have to spy on a function before attaching it as a listener. If this is my problem then I don't know how to resolve it: The spyOn syntax requires the object that the method is a property of (component in this case) but using component requires prior mounting of MyComponent which forces me to attach the listener first.

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

It may be relevant that my code uses React (and thus I include reactjs as a question tag) but somehow I doubt it.

推荐答案

对于这种测试,常见的路径是在您的您可以确定 onClick prop是由React团队测试的,而不是模拟事件。

For this kind of tests, the common path is to call your handler methods on your component instance instead of simulating the event.

您可以检查什么是他们调用您的处理程序时会发生什么。

You can be sure the onClick prop is test by the React team, what you can check is what happens when "they" call your handler.

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

This also allows you to use shallow rendering which at least for me is much faster. You can get a reference to the instance easily with the instance() method in your wrapper, and you can then call your handler and spy on whatever you want.

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

实际上,可能将你的间谍附加到实例的方法(已经被绑定)也会做到这一点。 :)

In fact, probably attaching your spies to the instance`s methods (that have already been binded) will do the trick as well. :)

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

希望它有帮助!

这篇关于即使我可以侦测其他方法,也不能监视事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆