为什么我的 React onChange 方法与酶 containsAllMatchingElements 测试中的箭头函数不匹配
Why doesn't my React onChange method match my arrow function in enzymes containsAllMatchingElements test
我写了一个测试用例,它试图测试 React 是否正确渲染了我的所有元素。
正在测试的代码:
...
eventDateChange(moment, dateType) {
const {handleEventChange} = this.props;
let {event} = this.state;
event[dateType] = moment.format("YYYY-MM-DD HH:mm");
this.setState({event});
handleEventChange(event);
};
render() {
return (
<div className="event-input">
<DateTime
onChange={moment => this.eventDateChange(moment,'startDate')}
inputProps={{placeholder: 'From:'}}
dateFormat="YYYY-MM-DD"/>
</div>
)
}
...
测试代码:
import React from "react";
import {expect} from "chai";
import {shallow} from "enzyme";
import EventInput from "../../../blog/event/EventInput.jsx";
import DateTime from "react-datetime";
describe('EventInput', () => {
it('is rendering an calendar icon', () => {
const wrapper = shallow(<EventInput/>);
expect(wrapper.containsAllMatchingElements([
<DateTime
onChange={moment => wrapper.instance.eventDateChange(moment,'startDate')}
inputProps={{placeholder: 'From:'}}
dateFormat="YYYY-MM-DD"/>
])).to.equal(true);
});
});
问题是我的 onChange 方法没有通过测试。如果我从代码和测试中删除 onChange 方法,则测试成功。
如您所见,我在测试中使用了 Mocha、Chai 和 Enzyme。
据我所知,除了 onChange 之外,所有道具都是相同的,我无法在测试中使用它,需要将其更改为实例。
查看 enzyme 如何比较节点的实现 (https://github.com/airbnb/enzyme/blob/d34630e9c3e07ca7983d37695d5668377f94a793/src/Utils.js#L102),看起来 enzyme 需要 "function" 类型的道具才能在进行此比较时完全匹配 (right[prop] === left[prop]
) 并且如果不满足此条件,将 return false。
您的 lambda 函数不相同,因此 ===
比较将失败。每当你使用 lambda 时,你都在创建一个新的匿名函数,所以即使两个 lambda 声明之间的参数和主体相同,它们实际上是两个独立的函数实例。
要解决此问题,您可以 1) 创建对组件中使用的确切函数实例的引用,以便您的测试可以引用它,或者 2) 在此处使用不同的酶 API。我建议#2。看起来你通过检查所有 属性 值有点过度测试,你可以改用这样的东西:
it('is rendering an calendar icon', () => {
const wrapper = shallow(<EventInput/>);
expect(wrapper.matchesElement(
<div>
<DateTime />
</div>
)).to.equal(true);
});
如果你想在 DateTime 上测试单个 props,你还可以做一些类似的事情:expect(wrapper.find("DateTime").props().dateFormat).to.equal("YYYY-MM-DD")
.
我写了一个测试用例,它试图测试 React 是否正确渲染了我的所有元素。
正在测试的代码:
...
eventDateChange(moment, dateType) {
const {handleEventChange} = this.props;
let {event} = this.state;
event[dateType] = moment.format("YYYY-MM-DD HH:mm");
this.setState({event});
handleEventChange(event);
};
render() {
return (
<div className="event-input">
<DateTime
onChange={moment => this.eventDateChange(moment,'startDate')}
inputProps={{placeholder: 'From:'}}
dateFormat="YYYY-MM-DD"/>
</div>
)
}
...
测试代码:
import React from "react";
import {expect} from "chai";
import {shallow} from "enzyme";
import EventInput from "../../../blog/event/EventInput.jsx";
import DateTime from "react-datetime";
describe('EventInput', () => {
it('is rendering an calendar icon', () => {
const wrapper = shallow(<EventInput/>);
expect(wrapper.containsAllMatchingElements([
<DateTime
onChange={moment => wrapper.instance.eventDateChange(moment,'startDate')}
inputProps={{placeholder: 'From:'}}
dateFormat="YYYY-MM-DD"/>
])).to.equal(true);
});
});
问题是我的 onChange 方法没有通过测试。如果我从代码和测试中删除 onChange 方法,则测试成功。
如您所见,我在测试中使用了 Mocha、Chai 和 Enzyme。
据我所知,除了 onChange 之外,所有道具都是相同的,我无法在测试中使用它,需要将其更改为实例。
查看 enzyme 如何比较节点的实现 (https://github.com/airbnb/enzyme/blob/d34630e9c3e07ca7983d37695d5668377f94a793/src/Utils.js#L102),看起来 enzyme 需要 "function" 类型的道具才能在进行此比较时完全匹配 (right[prop] === left[prop]
) 并且如果不满足此条件,将 return false。
您的 lambda 函数不相同,因此 ===
比较将失败。每当你使用 lambda 时,你都在创建一个新的匿名函数,所以即使两个 lambda 声明之间的参数和主体相同,它们实际上是两个独立的函数实例。
要解决此问题,您可以 1) 创建对组件中使用的确切函数实例的引用,以便您的测试可以引用它,或者 2) 在此处使用不同的酶 API。我建议#2。看起来你通过检查所有 属性 值有点过度测试,你可以改用这样的东西:
it('is rendering an calendar icon', () => {
const wrapper = shallow(<EventInput/>);
expect(wrapper.matchesElement(
<div>
<DateTime />
</div>
)).to.equal(true);
});
如果你想在 DateTime 上测试单个 props,你还可以做一些类似的事情:expect(wrapper.find("DateTime").props().dateFormat).to.equal("YYYY-MM-DD")
.