【发布时间】:2017-06-20 08:41:13
【问题描述】:
我想使用 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)无效。我显然 am 调用 clickHandler 为 otherMethod 如果我不是,则不会被调用,但 toHaveBeenCalled 不会以某种方式被 clickHandler 接听。为什么?
我知道我不必在otherMethod 上使用.bind(this) 或.and.callThrough(),但我同时使用这两种方法只是为了同样对待这两种方法,并且在otherMethod 上使用它们实际上不应该产生任何效果区别。
This other SO answer 声明我必须在将函数附加为侦听器之前对其进行监视。如果这是我的问题,那么我不知道如何解决它:spyOn 语法需要该方法是其属性的对象(在这种情况下为component),但使用component 需要事先安装@987654337 @ 这迫使我首先附加监听器。
我的代码使用 React 可能是相关的(因此我将 reactjs 作为问题标签包含在内)但不知何故我对此表示怀疑。
【问题讨论】:
-
主要问题是您试图窥探组件的内部。通常,您会向组件注入某种回调,或者作为 click 事件的结果进行异步调用。这些东西来自组件外部,很容易被监视(回调)或模拟(异步调用)。也许您的示例已简化,但您应该关注
this.otherMethod()的结果,而不是它被调用。
标签: javascript reactjs event-handling jasmine jestjs