我已经在React中开发了一段时间用于我的工作,但最近我被要求使用伊斯坦布尔获得一些~100%测试覆盖率的应用程序。在过去的几天里,我已经为这个应用程序单独写了160多个测试,但是我还没能覆盖我代码的某些部分。我在覆盖AJAX调用,setTimeout回调和需要其他组件正常运行的组件方法方面遇到的问题最多。 我读过几个SO问题都无济于事,我相信这是因为我接近这个问题不正确。我正在使用Enzyme,Chai断言,Mocha,伊斯坦布尔报道,sinon为间谍,并且因为我不能让sinon fakeServer工作而正在考虑nock。
以下是有问题的组件方法:
_getCategoriesFromServer() {
const _this = this;
sdk.getJSON(_this.props.sdkPath, {
itemsperpage: 10000
}).done(function(data) {
_this.setState({
isLoaded: true,
categories: _this.state.categories.concat(data)
});
});
}
以下是该组件的测试:
it('should call _getCategoriesFromServer', () => {
sinon.spy(CategoryTree.prototype, '_getCategoriesFromServer');
wrapper = mount(<CategoryTree {...props} />);
expect(CategoryTree.prototype._getCategoriesFromServer.calledOnce).to.be.true;
});
sdk只是一个使用getJSON构造jQuery API调用的模块。 我的测试覆盖了函数调用,但它没有覆盖此处显示的.done回调: 所以我的问题是,我怎样才能正确测试.done? 如果有人有文章,教程,视频,任何解释如何正确测试组件方法的东西,我真的很感激!
第二个问题是,我如何测试一个作为prop组件传递给子组件的方法?根据测试覆盖率要求,我必须测试该方法,但其唯一目的是传递给子组件以用作onClick。这很好,但onClick依赖于另一个AJAX调用返回子组件中的数据。 我最初的冲动是只使用酶.find找到onClick并模拟一个click事件,但是那个onClick的元素不存在,因为AJAX调用没有带回测试环境中的数据。 如果您已经读过这篇文章,我向您致敬。如果你能提供帮助,我感谢你!
答案 0 :(得分:5)
您可以使用重新布线(https://github.com/jhnns/rewire)来测试您的组件,如下所示:
// let's said your component is ListBox.js
var rewire = require("rewire");
var myComponent = rewire("../components/ListBox.js");
const onDone = sinon.spy()
const sdkMock = {
getJSON (uri, data) {
return this.call('get', uri, data);
},
call: function (method, uri, data) {
return { done: function(){ onDone() } }
}
};
myComponent.__set__("sdk", sdkMock);
最后你将测试是否像这样调用done函数:
expect(onDone.calledOnce)to.be.true
这应该按预期工作。如果您需要更多选项,您可以在GitHub中看到重新连接的所有选项。
<强> BABEL 强>
如果您使用babel作为转换器,则需要使用babel-plugin-rewire(https://github.com/speedskater/babel-plugin-rewire),您可以像这样使用它:
sdk.js
function call(method, uri, data) {
return fetch(method, uri, data);
}
export function getJSON(uri, data) {
return this.call('get', uri, data);
}
yourTest.js
import { getJSON, __RewireAPI__ as sdkMockAPI } from 'sdk.js';
describe('api call mocking', function() {
it('should use the mocked api function', function(done) {
const onDone = sinon.spy()
sdkMockAPI.__Rewire__('call', function() {
return { done: function(){ onDone() } }
});
getJSON('../dummy.json',{ data: 'dummy data'}).done()
expect(onDone.calledOnce)to.be.true
sdkMockAPI.__ResetDependency__('call')
})
})