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



我想使用Jest/Jasmine/Ezyme在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上使用它们实际上应该没有任何区别。

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

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

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

你可以确定onClick道具是由React团队测试的,你可以检查的是当"他们"调用你的处理程序时会发生什么。

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

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

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

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

希望它能有所帮助!

相关内容

  • 没有找到相关文章

最新更新