He estado desarrollando en React por un tiempo para mi trabajo, pero recientemente me pidieron que algunas aplicaciones tuvieran una cobertura de prueba de ~100% usando Istanbul. He escrito más de 160 pruebas solo para esta aplicación en los últimos días, pero no he podido cubrir ciertas partes de mi código. Tengo más problemas para cubrir llamadas AJAX, devoluciones de llamada setTimeout y métodos de componentes que requieren otro componente para funcionar correctamente. He leído varias preguntas SO en vano, y creo que es porque me estoy acercando a esto incorrectamente. Estoy usando Enzyme, afirmaciones de Chai, Mocha, cobertura de Estambul, sinon para espías, y estaba considerando nock ya que no puedo hacer funcionar sinon fakeServer.
Aquí está el método de componente en cuestión:
_getCategoriesFromServer() { const _this = this; sdk.getJSON(_this.props.sdkPath, { itemsperpage: 10000 }).done(function(data) { _this.setState({ isLoaded: true, categories: _this.state.categories.concat(data) }); });}
Aquí está la prueba para ese componente:
it('should call _getCategoriesFromServer', () => { sinon.spy(CategoryTree.prototype, '_getCategoriesFromServer'); wrapper = mount(<CategoryTree {...props} />); expect(CategoryTree.prototype._getCategoriesFromServer.calledOnce).to.be.true; }); El sdk es solo un módulo que construye una llamada API jQuery usando getJSON. Mi prueba cubre la llamada de función, pero no cubre la devolución de llamada .done que se ve aquí:
Entonces mi pregunta es, ¿cómo puedo probar correctamente el .done? Si alguien tiene un artículo, tutorial, video, cualquier cosa que explique cómo probar correctamente los métodos de componentes, ¡realmente lo agradecería!
La segunda pregunta es, ¿cómo puedo probar un método que se transmite como accesorio a un componente secundario? Con el requisito de cobertura de prueba, tengo que probar ese método, pero su único propósito es pasarlo a un componente secundario para usarlo como onClick. Lo cual está bien, pero ese onClick depende de otra llamada AJAX que devuelva datos EN el componente secundario. Mi impulso inicial fue simplemente usar enzimas .find para ubicar ese onClick y simular un evento de clic, pero el elemento con ese onClick no está allí porque la llamada AJAX no trajo datos en el entorno de prueba. Si has leído hasta aquí, te saludo. Y si me puedes ayudar te lo agradezco!
Podría usar rewire ( https://github.com/jhnns/rewire ) para probar su componente de esta manera:
// 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);y finalmente probará si la función terminada se llama así:
expect(onDone.calledOnce)to.be.trueCon esto debería funcionar como se esperaba. Si necesita más opciones, puede ver todas las opciones de reconexión en GitHub.
BABEL
Si está utilizando babel como transpilador, necesita usar babel-plugin-rewire ( https://github.com/speedskater/babel-plugin-rewire ), podría usarlo así:
sdk.js
function call(method, uri, data) { return fetch(method, uri, data); } export function getJSON(uri, data) { return this.call('get', uri, data); }tuPrueba.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') }) })