用 Sinon 存根 React 组件方法

IT技术 javascript reactjs stub sinon
2021-05-14 14:38:53

我正在尝试为测试目的存根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

可悲的是,这一直在控制台上打印“扑通”……并且断言失败了。

注意:直接存根 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 组件方法的策略吗?

2个回答

您遇到了 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 module中编写组件时,它可能会变得更有意义