我正在从摩卡交换开玩笑,我想知道是否有办法窥探反应方法.例如,假设我的组件中有以下方法(忽略sdk库,它只构造一个jquery ajax调用):
getData() {
sdk.getJSON('/someURL').done(data => {
this.setState({data});
});
}
Run Code Online (Sandbox Code Playgroud)
使用sinon我会通过监视原型来测试这个:
it('should call getData', () => {
sinon.spy(Component.prototype, 'getData');
mount(<Component />);
expect(Component.prototype.getData.calledOnce).to.be.true;
});
Run Code Online (Sandbox Code Playgroud)
这样可以确保代码覆盖而无需模拟方法.在jest中有类似的功能吗?
编辑:此外,如果此功能不存在,测试API调用的下一个最佳策略是什么?
我正在尝试测试我的react组件中的一个方法.按下按钮后调用它,所以我用酶进行了模拟
it('clone should call handleCloneClick when clicked', () => {
const cloneButton = wrapper.find('#clone-btn');
cloneButton.simulate('click');
});
Run Code Online (Sandbox Code Playgroud)
我的组件方法在这里:
_handleCloneClick(event) {
event.preventDefault();
event.stopPropagation();
this.props.handleClone(this.props.user.id);
}
Run Code Online (Sandbox Code Playgroud)
当用户点击模拟中的按钮时,会调用_handleCloneClick,如何测试成功调用它?
我已经在React中开发了一段时间用于我的工作,但最近我被要求使用伊斯坦布尔获得一些~100%测试覆盖率的应用程序.在过去的几天里,我已经为这个应用程序编写了160多个测试,但是我无法覆盖代码的某些部分.我在覆盖AJAX调用,setTimeout回调和需要其他组件正常运行的组件方法方面遇到的问题最多.我读过几个SO问题无济于事,我相信这是因为我正在接近这个问题.我正在使用Enzyme,Chai断言,Mocha,伊斯坦布尔报道,sinon为间谍,并且正在考虑nock,因为我不能让sinon fakeServer工作.
这是有问题的组件方法:
_getCategoriesFromServer() {
const _this = this;
sdk.getJSON(_this.props.sdkPath, {
itemsperpage: 10000
}).done(function(data) {
_this.setState({
isLoaded: true,
categories: _this.state.categories.concat(data)
});
});
Run Code Online (Sandbox Code Playgroud)
}
以下是该组件的测试:
it('should call _getCategoriesFromServer', () => {
sinon.spy(CategoryTree.prototype, '_getCategoriesFromServer');
wrapper = mount(<CategoryTree {...props} />);
expect(CategoryTree.prototype._getCategoriesFromServer.calledOnce).to.be.true;
});
Run Code Online (Sandbox Code Playgroud)
sdk只是一个使用getJSON构造jQuery API调用的模块.我的测试覆盖了函数调用,但它没有覆盖这里看到的.done回调:
所以我的问题是,我怎样才能正确测试.done?如果有人有文章,教程,视频,任何解释如何正确测试组件方法的东西,我真的很感激!
第二个问题是,我如何测试一个作为prop组件传递给子组件的方法?根据测试覆盖率要求,我必须测试该方法,但其唯一目的是传递给子组件以用作onClick.这很好,但onClick依赖于另一个AJAX调用返回子组件中的数据.我最初的冲动是只使用酶.find找到onClick并模拟一个click事件,但是那个onClick的元素不存在,因为AJAX调用没有带回测试环境中的数据.如果你读到这里,我向你致敬.如果你能提供帮助,我感谢你!
我正在测试一个组件,该组件呈现具有以下contextTypes的子组件:
Component.contextTypes = {router: PropTypes.object.isRequired}
Run Code Online (Sandbox Code Playgroud)
我是开玩笑的新手,但是来自摩卡/酶我从未遇到过这个问题.
我的第一个测试看起来像这样,我真的只是搞乱它看看它是如何工作的:
it('should exist', () => {
wrapper = renderer.create(<Companies/>);
let tree = wrapper.toJSON();
expect(tree).toMatchScreenshot();
});
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,我收到以下错误:
Failed context type: The context `router` is marked as required in `ChildComponent`, but its value is `undefined`.
Run Code Online (Sandbox Code Playgroud)
有没有解决这个问题,或者只是我缺少的文档中的某些内容?提前致谢!
解决方案:对于遇到同一问题的任何人,我在beforeEach()中使用了以下内容:
MyComponent.contextTypes = {
router: function () {
return {
transitionTo: jest.genMockFunction()
};
}
};
Run Code Online (Sandbox Code Playgroud) 我有一个子组件,从父母接收道具.在子组件中,它呈现一对像这样的单选按钮:
<div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="1"
checked={this.props.value === "1"}
/>
True
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="0"
checked={this.props.value === "0"}
/>
False
</label>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
handleInputChange只调用父方法,如下所示:
_handleInputChange(e) {
this.props.handleChange(e);
}
Run Code Online (Sandbox Code Playgroud)
将父组件的状态设置为单选按钮中选择的值(即"1"或"0").我遇到的问题是检查过的条件会返回正确的道具,但它们的功能很奇怪.几乎看起来当无线电输入接收到新的道具值时,它不会重新渲染checked.当组件首次渲染时,props.value是一个空字符串.当用户选择单选按钮时,它会更改父组件的状态,_handleInputChange然后将该值重新发送给条件.
我有一个组件,呈现一个像这样的选择元素:
<select
name="directoryAttributes"
id="dirSelect"
className="form-control"
onChange={this._handleChange}>
{
attributes.map(attribute => {
return (
<option
value={attribute}
key={attribute.directoryAttributesNo}
>{attribute.label}</option>
);
})
}
</select>
Run Code Online (Sandbox Code Playgroud)
attribute是一个带有一些键/值的普通对象.我想调用handleChange将我的组件状态设置为该选项值(即属性对象).这是我的handleChange
_handleChange(e) {
e.preventDefault();
const element = e.target;
const stateObject = {};
stateObject[element.name] = element.value;
this.setState(stateObject);
}
Run Code Online (Sandbox Code Playgroud)
问题是,它似乎设置状态directoryAttributes为[object Object].为什么会发生这种情况,是一种反应的怪癖还是一些缺失的东西?
提前致谢!
编辑:对象的属性数组来自状态,只是为了澄清