Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stubbing a React component method with Sinon

Tags:

I'm trying to stub a React component method for testing purpose:

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 

This sadly keeps printing "plop" onto the console… and the assertion fails.

Note: Directly stubbing the spec object method works, but then you have to export the component constructor and the spec separately so they're both available in tests… Also, you'd need to stub the spec before even creating the component class; not so convenient:

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 

Can you think of another strategy to easily stub a React component method?

like image 364
NiKo Avatar asked Jun 18 '14 08:06

NiKo


People also ask

What is stubbing Sinon?

What are stubs? Test stubs are functions (spies) with pre-programmed behavior. They support the full test spy API in addition to methods which can be used to alter the stub's behavior. As spies, stubs can be either anonymous, or wrap existing functions.

What is Componentref in react?

Components are independent and reusable bits of code. They serve the same purpose as JavaScript functions, but work in isolation and return HTML. Components come in two types, Class components and Function components, in this tutorial we will concentrate on Function components.

What is stub method in JavaScript?

What are Stubs? A test stub is a function or object that replaces the actual behavior of a module with a fixed response. The stub can only return the fixed response it was programmed to return.


2 Answers

You're running up against React's auto-binding feature, which caches the .bind(this) which is wrapped around your class methods. You can get your code to work by stubbing the cached version of the method in React's __reactAutoBindMap:

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 
like image 125
danvk Avatar answered Sep 20 '22 13:09

danvk


Which test framework are you using?

If you use jasmine, I've found jasmine-react to be a useful library for spying on React methods as well as replacing Components with test stubs.

In this case, you can spy on your method easily outside component definition.

//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 returns an ordinary jasmine spy that you can use to track calls to it and its arguments.

If you want to actually stub the method and make it return something, you can do something like jasmineReact.spyOnClass(Comp, "plop").andReturn('something')

Alternatively Facebook have recently launched a test framework Jest (also has jasmine as a dependency) which they use themselves for testing React components. Component methods can easily be stubbed using this framework. This looks like its worth checking out as well, but probably comes into its own a bit more when you write your components inside commonJS modules

like image 31
Ron Avatar answered Sep 19 '22 13:09

Ron