使用 Enzymes 测试 React Component Render 功能
React Component Render function testing using Enzymes
我最近开始测试 React App,但无法正确测试 React App。请看下面的场景
React 组件
class Filter extends Component {
constructor(props) {
super(props)
this.state = {
sheetNames:this.props.sheetNames?this.props.sheetNames:[],
sheetColumnDimensions:this.props.sheetColumnDimensions?this.props.sheetColumnDimensions:{},
}
}
render(){
let list=
this.state.sheetNames.map((sheetName,index)=>
<React.Fragment key={index}>
{
this.state.sheetColumnDimensions[sheetName].map((column,idx)=>
<option key={idx} value={column}>{column}</option>
)
}
</React.Fragment>
);
return (
<div>
<div id="fieldForFiltering">
<select id="columnForFilter"onChange={(event)=>this.handleOnChange(event)} >
{list}
</select>
</div>
</div>
)
}
export default Filter
上述组件的React测试脚本
import React from 'react';
import FilterDetails from "../Components/Filters/FilterDetails";
import Adapter from 'enzyme-adapter-react-16';
import {shallow} from 'enzyme';
import * as enzyme from 'enzyme';
enzyme.configure({ adapter: new Adapter() });
describe('FilterDetails component test suite', () => {
let props ={
sheetNames:["Stocks","Returns"],
sheetColumnDimensions:{Stocks:["Sales","Profit"],Returns:["Status","Quantity"]}
}
let wrapper = shallow(<FilterDetails {...props}/>);
it("should render initial layout of FilterDetails.jsx ", () => {
expect(wrapper.getElements()).toMatchSnapshot();
});
})
按上述方式测试应用程序时,我无法在快照中看到列表 <options value={column}>{column}</option>
,它只在 {list} 的位置不呈现任何内容,并且无法测试按钮点击以及此后与列表相关的所有内容.如何强制此渲染列表和测试?
提前致谢
在回答之前,我想提几个问题以及对代码的改进,这些问题不一定会导致测试失败,但更正它们可能会使测试通过。
state
中的逻辑改进。
这纯粹是基于偏好,但在这种情况下,三元运算符可以缩短为简单的 ||
,这也更易于读写。
this.state = {
sheetNames: this.props.sheetNames || [],
sheetColumnDimensions: this.props.sheetColumnDimensions || {},
};
- 缺少
handleOnChange
事件处理程序。
<select id="columnForFilter" onChange={(event) => this.handleOnChange(event)}>
{list}
</select>
您正在调用 <select>
中的事件处理程序,上面发布的代码中缺少该事件处理程序,测试可能不会引发任何错误。
这里可以再做一个小改进。代替 onChange={(event) => this.handleOnChange(event)}
,只需 onChange={this.handleOnChange}
也可以完成这项工作。
- 语法错误:末尾缺少
'}'
。
缺少 class 的右大括号。测试抛出关于相同的错误。
回答
我尝试使用您提供的代码在本地重现该问题(已更正语法错误)。除了语法错误,我找不到任何错误,如下所示,快照确实包含 {list}
,即 <option> .. </option>
.
exports[`FilterDetails component test suite should render initial layout of FilterDetails.jsx 1`] = `
Array [
<div>
<div
id="fieldForFiltering"
>
<select
id="columnForFilter"
onChange={[Function]}
>
<React.Fragment>
<option
value="Sales"
>
Sales
</option>
<option
value="Profit"
>
Profit
</option>
</React.Fragment>
<React.Fragment>
<option
value="Status"
>
Status
</option>
<option
value="Quantity"
>
Quantity
</option>
</React.Fragment>
</select>
</div>
</div>,
]
`;
您可以尝试以下几件事:
进行上述改进并尝试是否正确生成快照。
快照可能已过时。当您进行任何更改和 re-run 测试时,默认情况下不会更新快照。要在每次更改时更新快照,请更新 package.json
.
中的测试脚本
创建 React 应用程序
scripts: {
"test": "react-scripts test --env=jsdom --updateSnapshot"
}
开玩笑
scripts: {
"test": "jest --updateSnapshot"
}
- 如果上述方法均无效,请尝试删除并重新安装
node_modules
。
我最近开始测试 React App,但无法正确测试 React App。请看下面的场景
React 组件
class Filter extends Component {
constructor(props) {
super(props)
this.state = {
sheetNames:this.props.sheetNames?this.props.sheetNames:[],
sheetColumnDimensions:this.props.sheetColumnDimensions?this.props.sheetColumnDimensions:{},
}
}
render(){
let list=
this.state.sheetNames.map((sheetName,index)=>
<React.Fragment key={index}>
{
this.state.sheetColumnDimensions[sheetName].map((column,idx)=>
<option key={idx} value={column}>{column}</option>
)
}
</React.Fragment>
);
return (
<div>
<div id="fieldForFiltering">
<select id="columnForFilter"onChange={(event)=>this.handleOnChange(event)} >
{list}
</select>
</div>
</div>
)
}
export default Filter
上述组件的React测试脚本
import React from 'react';
import FilterDetails from "../Components/Filters/FilterDetails";
import Adapter from 'enzyme-adapter-react-16';
import {shallow} from 'enzyme';
import * as enzyme from 'enzyme';
enzyme.configure({ adapter: new Adapter() });
describe('FilterDetails component test suite', () => {
let props ={
sheetNames:["Stocks","Returns"],
sheetColumnDimensions:{Stocks:["Sales","Profit"],Returns:["Status","Quantity"]}
}
let wrapper = shallow(<FilterDetails {...props}/>);
it("should render initial layout of FilterDetails.jsx ", () => {
expect(wrapper.getElements()).toMatchSnapshot();
});
})
按上述方式测试应用程序时,我无法在快照中看到列表 <options value={column}>{column}</option>
,它只在 {list} 的位置不呈现任何内容,并且无法测试按钮点击以及此后与列表相关的所有内容.如何强制此渲染列表和测试?
提前致谢
在回答之前,我想提几个问题以及对代码的改进,这些问题不一定会导致测试失败,但更正它们可能会使测试通过。
state
中的逻辑改进。
这纯粹是基于偏好,但在这种情况下,三元运算符可以缩短为简单的 ||
,这也更易于读写。
this.state = {
sheetNames: this.props.sheetNames || [],
sheetColumnDimensions: this.props.sheetColumnDimensions || {},
};
- 缺少
handleOnChange
事件处理程序。
<select id="columnForFilter" onChange={(event) => this.handleOnChange(event)}>
{list}
</select>
您正在调用 <select>
中的事件处理程序,上面发布的代码中缺少该事件处理程序,测试可能不会引发任何错误。
这里可以再做一个小改进。代替 onChange={(event) => this.handleOnChange(event)}
,只需 onChange={this.handleOnChange}
也可以完成这项工作。
- 语法错误:末尾缺少
'}'
。
缺少 class 的右大括号。测试抛出关于相同的错误。
回答
我尝试使用您提供的代码在本地重现该问题(已更正语法错误)。除了语法错误,我找不到任何错误,如下所示,快照确实包含 {list}
,即 <option> .. </option>
.
exports[`FilterDetails component test suite should render initial layout of FilterDetails.jsx 1`] = `
Array [
<div>
<div
id="fieldForFiltering"
>
<select
id="columnForFilter"
onChange={[Function]}
>
<React.Fragment>
<option
value="Sales"
>
Sales
</option>
<option
value="Profit"
>
Profit
</option>
</React.Fragment>
<React.Fragment>
<option
value="Status"
>
Status
</option>
<option
value="Quantity"
>
Quantity
</option>
</React.Fragment>
</select>
</div>
</div>,
]
`;
您可以尝试以下几件事:
进行上述改进并尝试是否正确生成快照。
快照可能已过时。当您进行任何更改和 re-run 测试时,默认情况下不会更新快照。要在每次更改时更新快照,请更新
中的测试脚本package.json
.
创建 React 应用程序
scripts: {
"test": "react-scripts test --env=jsdom --updateSnapshot"
}
开玩笑
scripts: {
"test": "jest --updateSnapshot"
}
- 如果上述方法均无效,请尝试删除并重新安装
node_modules
。