即使我可以侦测其他方法,也不能监视事件处理程序 [英] Can't spy on an event handler even though I can spy on other methods
问题描述
我想使用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屋!