Reactjs Ezyme/Mocha:如何通过从子组件触发onChange事件来测试react组件的功能
我用酶/摩卡来测试我的反应成分 我有一个正在测试的父组件Reactjs Ezyme/Mocha:如何通过从子组件触发onChange事件来测试react组件的功能,reactjs,mocha.js,enzyme,Reactjs,Mocha.js,Enzyme,我用酶/摩卡来测试我的反应成分 我有一个正在测试的父组件 let wrapper = mount(<Parent />); let wrapper=mount(); 这个父对象在其渲染函数中有一个子组件 render: function() { <Child onChange={this.foo} /> }, foo: function() { console.log("I was called"); } render:function(){ },
let wrapper = mount(<Parent />);
let wrapper=mount();
这个父对象在其渲染函数中有一个子组件
render: function() {
<Child onChange={this.foo} />
},
foo: function() {
console.log("I was called");
}
render:function(){
},
foo:function(){
log(“我被叫”);
}
我想启动孩子的onChange函数,这样我就可以测试我父母的foo函数
到目前为止,我还没有找到办法做到这一点——我读过关于sinon和Stubing的文章,但主要是关于拦截函数而不是启动它们
下面的测试
shallow(<Parent />).instance().foo();
shallow().instance().foo();
是一个弱测试,因为它不测试连接我的孩子和父母的代码行,如果我没有为我的孩子编写单元测试,它也不测试孩子的onChange功能。IMHO-如果将我的组件分解为父/子组件意味着更少的可测试性-那么这个框架就有问题了
任何帮助都将不胜感激,谢谢尝试将您的测试分解为多个部分。例如 首先,测试预期函数是否已传递给子组件:
import { shallow } from 'enzyme';
const actual = shallow(<Parent />);
const expected = <Child onChange={actual.instance().foo} />
expect(actual.matchesElement(expected)).true;
您可以单独测试您的子组件
以及它如何处理它的onChange
prop
这里使用的一些酶API:
- 这是我在很多测试中做的事情。我发现最适合我的方法是手动调用子组件的
onChange
处理程序,并根据您预期的结果进行断言
假设有一个父组件,看起来像这样:
import React from 'react';
import Child from './child';
export default class extends React.Component {
render() {
return (
<div>
<Child onChange={this.foo} />
</div>
);
}
foo() {
console.log('bar');
}
}
我之所以喜欢这种方法,是因为它是在测试组件的行为,而不是简单地测试它作为一个道具传递给一个函数,而这个道具恰好等于另一个函数。这不是一个坏主意,但一般来说,它不是在测试功能,而是在比较字符串。匹配和简单检查渲染函数在每次提交时没有更改有什么区别?另外,Parent包含大约10个组件,我正在简化这个问题。请参见下面的示例中我的注释:对于任何复杂的渲染,最好使用
find
api来定位子级并断言它已按预期进行了修饰。如果在Parent测试中测试foo()
方法,以及孩子在子测试中触发props.onChange()
(使用sinon.spy()
)的能力,那么在我看来,如果孩子调用props.onChange
,你不需要测试React可以调用this.foo
。就像您不需要在状态更改时测试React调用render()
,或者在props更改时测试componentWillReceiveProps()
。
import React from 'react';
import Child from './child';
export default class extends React.Component {
render() {
return (
<div>
<Child onChange={this.foo} />
</div>
);
}
foo() {
console.log('bar');
}
}
import Foo from './foo';
import React from 'react';
import {shallow} from 'enzyme';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import chai, {expect} from 'chai';
describe('Foo', () => {
let renderedElement;
function renderComponent() {
const componentElement = React.createElement(Foo);
renderedElement = shallow(componentElement);
}
before(() => {
chai.use(sinonChai);
});
it('should log the string "bar" when the child component is changed', () => {
//step 1
sinon.stub(console, 'log');
//step 2
renderComponent();
const childComponent = renderedElement.props().children;
//step 3
childComponent.props.onChange();
//step 4
expect(console.log).to.have.callCount(1);
expect(console.log).to.be.calledWith('bar');
//clean up
console.log.restore();
});
});