我已经在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) }); });
}
以下是该组件的测试:
it('should call _getCategoriesFromServer', () => { sinon.spy(CategoryTree.prototype, '_getCategoriesFromServer'); wrapper = mount(); expect(CategoryTree.prototype._getCategoriesFromServer.calledOnce).to.be.true; });
sdk只是一个使用getJSON构造jQuery API调用的模块.我的测试覆盖了函数调用,但它没有覆盖这里看到的.done回调: 所以我的问题是,我怎样才能正确测试.done?如果有人有文章,教程,视频,任何解释如何正确测试组件方法的东西,我真的很感激!
第二个问题是,我如何测试一个作为prop组件传递给子组件的方法?根据测试覆盖率要求,我必须测试该方法,但其唯一目的是传递给子组件以用作onClick.这很好,但onClick依赖于另一个AJAX调用返回子组件中的数据.我最初的冲动是只使用酶.find找到onClick并模拟一个click事件,但是那个onClick的元素不存在,因为AJAX调用没有带回测试环境中的数据.如果你读到这里,我向你致敬.如果你能提供帮助,我感谢你!
您可以使用重新连接(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') }) })