Enzyme/Mocha:如何通过从 child 组件触发 onChange 事件来测试 React 组件功能
Enzyme/Mocha: How to test a react component function by firing an onChange event from a child component
我正在使用 enzyme/mocha 来测试我的 React 组件。
我有一个正在测试的 parent 组件。
let wrapper = mount(<Parent />);
并且这个 parent 在它的渲染函数中有一个 child 组件
render: function() {
<Child onChange={this.foo} />
},
foo: function() {
console.log("I was called");
}
我希望触发 child 的 onChange 函数,以便我可以测试 parent 的 foo 函数。
到目前为止,我还没有找到执行此操作的方法 - 我已经阅读了有关 sinon 和存根的内容,但这主要是关于拦截函数而不是触发它们。
下面测试
shallow(<Parent />).instance().foo();
是一个弱测试,因为它不测试连接我的 child 和 parent 的代码行,以防我没有为我的 [=33= 编写单元测试],它也不测试 child 的 onChange 功能。恕我直言 - 如果将我的组件分解为 parents/children 意味着可测试性降低 - 那么这个框架有问题
任何帮助将不胜感激,谢谢
试着把你的测试分成几个部分。例如...
首先,测试预期的功能是否已传递给您的子组件:
import { shallow } from 'enzyme';
const actual = shallow(<Parent />);
const expected = <Child onChange={actual.instance().foo} />
expect(actual.matchesElement(expected)).true;
当我正在测试的组件中几乎没有渲染时,我喜欢使用上面的简单 matchesElement
方法,但您也可以使用 find
选择器来查找 Child
实例然后测试它。
然后单独测试你的 foo 函数:
import { shallow } from 'enzyme';
const actual = shallow(<Parent />).instance().foo();
const expected = 'expected return of foo'
expect(actual).equals(expected);
您可以单独测试 Child
组件以及它如何处理它的 onChange
属性。
这里使用了一些酶 API:
另见:
这是我在很多测试中所做的事情。我发现最适合我的方法是手动调用 child 组件的 onChange
处理程序,并根据预期结果发生的行为做出断言。
假设您有一个如下所示的 Parent 组件:
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');
}
}
传递给 child 的 onChange
属性将在调用时记录字符串 'bar'。这是我们要测试的行为。为此,我们需要执行以下步骤:
Stub console.log
使用你选择的模拟库(我将在这个例子中使用 Sinon)
创建 Parent 组件的浅实例,并获取对其 Child 的引用。
手动调用 Child 的 onChange
属性。
断言 console.log
被调用了一次,并且只有一个参数:'bar'
下面是我的做法(使用 mocha 和 chai):
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();
});
});
我喜欢这种方法的原因是因为它测试组件 行为 而不是简单地测试它是否作为 prop 传递给它恰好等于另一个函数。
我正在使用 enzyme/mocha 来测试我的 React 组件。
我有一个正在测试的 parent 组件。
let wrapper = mount(<Parent />);
并且这个 parent 在它的渲染函数中有一个 child 组件
render: function() {
<Child onChange={this.foo} />
},
foo: function() {
console.log("I was called");
}
我希望触发 child 的 onChange 函数,以便我可以测试 parent 的 foo 函数。
到目前为止,我还没有找到执行此操作的方法 - 我已经阅读了有关 sinon 和存根的内容,但这主要是关于拦截函数而不是触发它们。
下面测试
shallow(<Parent />).instance().foo();
是一个弱测试,因为它不测试连接我的 child 和 parent 的代码行,以防我没有为我的 [=33= 编写单元测试],它也不测试 child 的 onChange 功能。恕我直言 - 如果将我的组件分解为 parents/children 意味着可测试性降低 - 那么这个框架有问题
任何帮助将不胜感激,谢谢
试着把你的测试分成几个部分。例如...
首先,测试预期的功能是否已传递给您的子组件:
import { shallow } from 'enzyme';
const actual = shallow(<Parent />);
const expected = <Child onChange={actual.instance().foo} />
expect(actual.matchesElement(expected)).true;
当我正在测试的组件中几乎没有渲染时,我喜欢使用上面的简单 matchesElement
方法,但您也可以使用 find
选择器来查找 Child
实例然后测试它。
然后单独测试你的 foo 函数:
import { shallow } from 'enzyme';
const actual = shallow(<Parent />).instance().foo();
const expected = 'expected return of foo'
expect(actual).equals(expected);
您可以单独测试 Child
组件以及它如何处理它的 onChange
属性。
这里使用了一些酶 API:
另见:
这是我在很多测试中所做的事情。我发现最适合我的方法是手动调用 child 组件的 onChange
处理程序,并根据预期结果发生的行为做出断言。
假设您有一个如下所示的 Parent 组件:
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');
}
}
传递给 child 的 onChange
属性将在调用时记录字符串 'bar'。这是我们要测试的行为。为此,我们需要执行以下步骤:
Stub
console.log
使用你选择的模拟库(我将在这个例子中使用 Sinon)创建 Parent 组件的浅实例,并获取对其 Child 的引用。
手动调用 Child 的
onChange
属性。断言
console.log
被调用了一次,并且只有一个参数:'bar'
下面是我的做法(使用 mocha 和 chai):
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();
});
});
我喜欢这种方法的原因是因为它测试组件 行为 而不是简单地测试它是否作为 prop 传递给它恰好等于另一个函数。