Stubbing un método de componente React con Sinon


Estoy tratando de obtener un método de componente React para fines de prueba:

var Comp = React.createClass({
  displayName: "Comp",

  plop: function() {
    console.log("plop");
  },

  render: function() {
    this.plop();
    return React.DOM.div(null, "foo");
  }
});

var stub = sinon.stub(Comp.type.prototype, "plop");
React.addons.TestUtils.renderIntoDocument(Comp());
sinon.assert.called(stub); // throws

Esto lamentablemente sigue imprimiendo "plop" en la consola and y la afirmación falla.

Nota: Directamente stubbing el método de objeto spec funciona, pero entonces usted tiene que exportar el constructor de componentes y la especificación por separado para que ambos están disponibles en pruebas Also También, usted tendría que stub la especificación antes incluso de crear la clase de componente; no es tan conveniente:

var CompSpec = {
  displayName: "Comp",

  plop: function() {
    console.log("plop");
  },

  render: function() {
    this.plop();
    return React.DOM.div("foo");
  }
};

var stub = sinon.stub(CompSpec, "plop");
var Comp = React.createClass(CompSpec);
React.addons.TestUtils.renderIntoDocument(Comp());

// plop() is properly stubbed, so you can
sinon.assert.called(stub); // pass

¿Puedes pensar en otro estrategia para atornillar fácilmente un método de componente React?

Author: Deduplicator, 2014-06-18

2 answers

Te estás topando con la función de enlace automático de React, que almacena en caché el .bind(this) que está envuelto alrededor de tus métodos de clase. Puedes hacer que tu código funcione rellenando la versión en caché del método en el __reactAutoBindMap de React:

var Comp = React.createClass({
  displayName: "Comp",

  plop: function() {
    console.log("plop");
  },

  render: function() {
    this.plop();
    return React.DOM.div(null, "foo");
  }
});

// with older versions of React, you may need to use
// Comp.type.prototype instead of Comp.prototype
var stub = sinon.stub(Comp.prototype.__reactAutoBindMap, "plop");  // <--
React.addons.TestUtils.renderIntoDocument(React.createElement(Comp));
sinon.assert.called(stub);  // passes
 29
Author: danvk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-23 17:26:51

¿Qué marco de prueba está utilizando?

Si usas jasmine, he encontrado que jasmine-react es una biblioteca útil para espiar métodos React, así como para reemplazar Componentes con stubs de prueba.

En este caso, puede espiar su método fácilmente fuera de la definición de componente.

//Component Definition
var Comp = React.createClass({

    displayName: "Comp",

    plop: function() {
       console.log("plop");
    },

    render: function() {
       this.plop();
       return React.DOM.div(null, "foo");
    }
});

//test
it("should call plop method on render", function(){
   //spy on method
   jasmineReact.spyOnClass(Comp, "plop");
   React.addons.TestUtils.renderIntoDocument(Comp());
   expect(Comp.plop).toHaveBeenCalled();
})

jasmineReact.spyOnClass devuelve un espía jasmine ordinario que puede usar para rastrear llamadas a él y sus argumentos.

Si usted quiere realmente stub el método y hacer que devuelva algo, usted puede hacer algo como jasmineReact.spyOnClass(Comp, "plop").andReturn('something')

Alternativamente, Facebook ha lanzado recientemente un marco de prueba Jest (también tiene jasmine como dependencia) que utilizan ellos mismos para probar los componentes de React. Los métodos de componentes se pueden rellenar fácilmente usando este marco. Esto parece que vale la pena echarle un vistazo, así, pero probablemente entra en su propio un poco más cuando escribes tus componentes dentro de módulos CommonJS

 5
Author: Ron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-23 10:57:19