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?
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