Sinon.js - 在实例化组件之前,React组件的功能是什么?

Mic*_*ker 8 javascript sinon reactjs

假设我有一个看起来像这样的组件:

var React = require('react/addons');

var ExampleComponent = React.createClass({
    test : function () {
        return true;
    },
    render : function () {
        var test = this.test();
        return (
            <div className="test-component">
                Test component - {test}
            </div>
        );
    }
});

module.exports = ExampleComponent;
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我可以使用这个组件来渲染这个组件TestUtils,然后如下所示:

var renderedComponent = TestUtils.renderIntoDocument(<ExampleComponent/>);
sinon.stub(renderedComponent, 'test').returns(false);
expect(renderedComponent.test).toBe(false); //passes
Run Code Online (Sandbox Code Playgroud)

但有没有一种方法可以告诉Sinon每次创建该组件的实例时都会自动删除组件的功能?例如:

sinon.stubAll(ExampleComponent, 'test').returns(false); //something like this
var renderedComponent = TestUtils.renderIntoDocument(<ExampleComponent/>);
expect(renderedComponent.test).toBe(false); //I'd like this to pass
Run Code Online (Sandbox Code Playgroud)

如果这是不可能的,是否有一个潜在的解决方案接近提供我正在寻找的功能?

Vic*_*tor 16

你需要覆盖ExampleComponent.prototype而不是ExampleComponent.ExampleComponent是一个构造函数.像这样的本地方法test()保存在其中prototype.

sinon.stub(ExampleComponent.prototype, 'test').returns(false);
var renderedComponent = TestUtils.renderIntoDocument(<ExampleComponent/>);
expect(renderedComponent.test).toBe(false); //passes
Run Code Online (Sandbox Code Playgroud)


Mic*_*ker 3

我找到了解决问题的方法。

澄清一下,我的问题是我想删除属于在父组件下呈现的子组件的函数。所以像这样:

父.js

var Child = require('./child.js');
var Parent = React.createClass({
    render : function () {
        return (
            <div className="parent">
                <Child/>
            </div>
        );
    }
});
module.exports = Parent;
Run Code Online (Sandbox Code Playgroud)

孩子.js

var Child = React.createClass({
    test : function () {
        return true;
    },
    render : function () {
        if (this.test) {
            throw('boom');
        }
        return (
            <div className="child">
                Child
            </div>
        );
    }
});
module.exports = Child;
Run Code Online (Sandbox Code Playgroud)

如果我要在其中一个测试中使用 TestUtils 渲染 Parent,它会抛出错误,这是我想避免的。所以我的问题是我需要去掉 Child 的test在实例化 Child 的函数之前将其存根。然后,当我渲染 Parent 时,Child 就不会爆炸。

提供的答案不太有效,因为 Parent 用来require()获取 Child 的构造函数。我不知道为什么,但正因为如此,我无法在测试中删除 Child 的原型并期望测试通过,如下所示:

var React = require('react/addons'),
    TestUtils = React.addons.TestUtils,
    Parent = require('./parent.js'),
    Child = require('./child.js'),
    sinon = require('sinon');

describe('Parent', function () {
    it('does not blow up when rendering', function () {
        sinon.stub(Child.prototype, 'test').returns(false);
        var parentInstance = TestUtils.renderIntoDocument(<Parent/>); //blows up
        expect(parentInstance).toBeTruthy();
    });
});
Run Code Online (Sandbox Code Playgroud)

不过,我能够找到适合我需求的解决方案。我将测试框架从 Mocha 切换到 Jasmine,并开始使用jasmine-react,它提供了多个好处,包括能够在实例化类之前将其功能存根。这是一个可行的解决方案的示例:

var React = require('react/addons'),
    Parent = require('./parent.js'),
    Child = require('./child.js'),
    jasmineReact = require('jasmine-react-helpers');

describe('Parent', function () {
    it('does not blow up when rendering', function () {
        jasmineReact.spyOnClass(Child, 'test').and.returnValue(false);
        var parentInstance = jasmineReact.render(<Parent/>, document.body); //does not blow up
        expect(parentInstance).toBeTruthy(); //passes
    });
});
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助其他遇到类似问题的人。如果有人有任何疑问,我很乐意提供帮助。