用Sinon存根一个React组件方法

Stubbing a React component method with Sinon

本文关键字:一个 React 组件 方法 Sinon 存根      更新时间:2023-09-26

我正在尝试存根一个React组件方法用于测试目的:

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

不幸的是,这将继续在控制台上打印"plop"…并且断言失败。

注意:直接存根spec对象方法是有效的,但是你必须分别导出组件构造函数和spec,这样它们在测试中都可用…此外,你需要在创建组件类之前存根spec;不太方便:

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

你能想到另一种策略来轻松地存根React组件方法吗?

您遇到了React的自动绑定功能,该功能缓存了包装在类方法周围的.bind(this)。您可以通过在React的__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

您使用的是哪个测试框架?

如果你使用jasmine,我发现jasmine- React是一个很有用的库,可以监视React方法,也可以用测试存根替换组件。

在这种情况下,您可以轻松地在组件定义之外监视您的方法。
//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返回一个普通的茉莉间谍,你可以用它来跟踪调用它和它的参数。

如果你想要存根方法并让它返回一些东西,你可以这样做jasmineReact.spyOnClass(Comp, "plop").andReturn('something')

另外,Facebook最近推出了一个测试框架Jest(也依赖于jasmine),他们自己用它来测试React组件。使用这个框架可以很容易地对组件方法进行存根处理。这看起来也值得一试,但当你在commonJS模块中编写组件时,可能会有更多的用处