javascript Sinon.js - 在实例化组件之前存根 React 组件的功能?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30918993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sinon.js - stub React component's function before component is instantiated?
提问by Michael Parker
Let's say I have a component that looks like this:
假设我有一个如下所示的组件:
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;
In my test, I could render this component using TestUtils
, then stub out the method like so:
在我的测试中,我可以使用 渲染这个组件TestUtils
,然后像这样存根方法:
var renderedComponent = TestUtils.renderIntoDocument(<ExampleComponent/>);
sinon.stub(renderedComponent, 'test').returns(false);
expect(renderedComponent.test).toBe(false); //passes
But is there a way I could tell Sinon to automatically stub out a component's function every time an instance of that component is created? Ex:
但是有没有一种方法可以告诉 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
If this isn't possible, is there a potential solution that comes close to providing the functionality I'm looking for?
如果这是不可能的,是否有接近提供我正在寻找的功能的潜在解决方案?
采纳答案by Michael Parker
I found a solution to my problem.
我找到了解决我的问题的方法。
To clarify, my problem is that I wanted to stub out functions that belong to children components that are rendered under a parent component. So something like this:
澄清一下,我的问题是我想删除属于在父组件下呈现的子组件的函数。所以像这样:
parent.js
父.js
var Child = require('./child.js');
var Parent = React.createClass({
render : function () {
return (
<div className="parent">
<Child/>
</div>
);
}
});
module.exports = Parent;
child.js
child.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;
If I were to use TestUtils to render Parent in one of my tests, it would throw the error, which I wanted to avoid. So my problem was that I needed to stub out Child's test
function before it was instantiated. Then, when I render Parent, Child won't blow up.
如果我在其中一个测试中使用 TestUtils 来呈现 Parent,它会抛出错误,这是我想要避免的。所以我的问题是我需要test
在实例化Child 的函数之前存根。然后,当我渲染父级时,子级不会爆炸。
The answer provided did not quite work, as Parent uses require()
to get Child's constructor. I'm not sure why, but because of that, I can't stub out Child's prototype in my test and expect the test to pass, like so:
提供的答案并不完全有效,因为 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();
});
});
I was able to find a solution that fit my needs though. I switched my testing framework from Mocha to Jasmine, and I started using jasmine-react, which provided several benefits, including the ability to stub out a function of a class before it is instantiated. Here is an example of a working solution:
不过,我能够找到适合我需求的解决方案。我将我的测试框架从 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
});
});
I hope this helps someone else with a similar issue. If anyone has any questions I would be glad to help.
我希望这可以帮助其他有类似问题的人。如果有人有任何问题,我很乐意提供帮助。
回答by Victor
You will need to overwrite the ExampleComponent.prototype
instead of ExampleComponent
. ExampleComponent
is a constructor. Local methods like test()
are saved in it's prototype
.
您将需要覆盖ExampleComponent.prototype
而不是ExampleComponent
。ExampleComponent
是一个构造函数。像这样的本地方法test()
保存在它的prototype
.
sinon.stub(ExampleComponent.prototype, 'test').returns(false);
var renderedComponent = TestUtils.renderIntoDocument(<ExampleComponent/>);
expect(renderedComponent.test).toBe(false); //passes