reactjs - 如何使用反应、笑话和酶对自定义表格单元格渲染器功能进行单元测试?
问题描述
我想测试一个返回 JSX 内容的 React 类组件函数。下面是我的代码:
产品组成
export default class Products extends React.Component {
constructor(props) {
super(props);
this.state = {
products: [],
};
}
iconRenderer = (data) => {
return (
<i
className="fa fa-qrcode fa-3x"
>
</i>
);
};
getDisplayColumns = () => {
return [
{
fieldName: 'producticon',
displayText: 'Name',
isEditable: false,
visible: true,
columnSize: 2,
renderer: this.iconRenderer
}
];
};
render() {
const displayColumns = this.getDisplayColumns();
return (
<div className=''>
{this.state.products && this.state.products.length > 0 &&
<CustomTableGeneric
tableId="item-list-table"
data={this.state.products}
columns={displayColumns}
>
</CustomTableGeneric>
}
</div>
);
}
}
CustomTableGeneric组件(我试图简化代码)
export default class CustomTableGeneric extends React.Component {
constructor(props) {
super(props);
this.state = {
currentTableData: [],
columnsToDisplay: [],
};
this.renderRows = this.renderRows.bind(this);
this.renderIndividualRow = this.renderIndividualRow.bind(this);
}
renderIndividualRow(data, dataKeys) {
return dataKeys.map((item, index) => {
let currentRowId = data['id'];
let columnWidth = this.state.columnsToDisplay[index].columnSize;
if (item.renderer) {
return (
<Col md={columnWidth} className="table-column-cell"
key={index}>
{item.renderer(data, item.fieldName)}
</Col>
);
} else {
return (
<Col md={columnWidth} className="table-column-cell" key={index}>{data[item.fieldName]}</Col>
);
}
});
}
renderRows() {
let dataKeys = clonedeep(this.state.columnsToDisplay);
let dataRows = clonedeep(this.state.currentTableData);
if (dataRows.length > 0) {
return dataRows.map((row, index) => {
return (
<Row key={index} className="table-row">
{this.renderIndividualRow(row, dataKeys)}
</Row>
);
});
}
}
render() {
return (
<Row id={this.props.tableId}>
<Col className="custom-table">
<Row className="table-header">
{this.renderHeaders()}
</Row>
{this.renderRows()}
</Col>
</Row>
);
}
}
CustomTableGeneric.propTypes = {
tableId: PropTypes.string,
data: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.shape({
fieldName: PropTypes.string,
displayText: PropTypes.string,
renderer: PropTypes.func,
})).isRequired,
};
Products.test.js
import React from 'react';
import {shallow, mount} from 'enzyme';
import CustomTableGeneric from '../../components/CustomTableGeneric';
import Products from './Products';
const props = {
id: '123'
};
describe('Products function tests', () => {
it('should call the iconRenderer function', () => {
const wrapper = shallow(<Products {...props} />);
const result = wrapper
.instance()
.iconRenderer();
console.log(result);
});
});
下面是我运行测试时的控制台输出。
{ '$$typeof': Symbol(react.element),
type: 'i',
key: null,
ref: null,
props: { className: 'fa fa-qrcode fa-3x' },
_owner: null,
_store: {} }
如您所见,如果我从测试中显式调用iconRenderer(),它正在执行。但是我要测试的是检查在渲染Products组件时是否调用了iconRenderer() 。请看我如何在渲染函数中调用它,例如 Products render() -> getDisplayColumns() -> CustomTableGeneric() -> iconRenderer()。
下面是我要运行的实际测试
describe('Products function tests', () => {
it('should call the iconRenderer function', () => {
const wrapper = shallow(<Products {...props} />);
jest.spyOn(wrapper.instance(), 'iconRenderer');
expect(wrapper.instance().iconRenderer()).toHaveBeenCalled();
});
});
但我得到以下错误
Error: expect(jest.fn())[.not].toHaveBeenCalled()
jest.fn() value must be a mock function or spy.
Received:
object: <i className="fa fa-qrcode fa-3x" />
任何建议都受到高度赞赏。
解决方案
在我看来,您的代码有两个问题:
您无意中调用了 in 中的模拟函数
expect
,这会导致错误:expect
正在接收模拟的返回值iconRenderer
,而不是模拟本身。将您的行更改expect
为:expect(wrapper.instance().iconRenderer).toHaveBeenCalled();
您需要
iconRenderer
在渲染之前进行模拟Product
,因此在渲染时调用它Product
。因此,需要在此行之前对其进行模拟:const wrapper = shallow(<Products {...props} />);
您可以在这个问题中看到如何做到这一点的示例。
推荐阅读
- transformation - 当ros中有些是静态的而有些是动态的时,如何在多个帧之间进行转换?
- c++ - 在服务器上获取 post 请求并将其转换为 json
- laravel - Laravel 5 在哪里和在哪里
- testng - 在 Maven 依赖项(pom.xml)中添加 TestNG 后,TestNG 在 selenium 中不可用
- ruby-on-rails - aws 的 Procfile 替代方案
- python - 通过 cat PYTHON 从文件中读取内容时出现“索引超出范围”
- performance - Networkx : 删除节点后的全局效率
- python - 启动脚本中的 Feh 仅在重新启动时显示图像,而不是启动?
- javascript - create-react-app 的最佳 Service Worker 策略是什么?
- reactjs - Typescript 和 React:使用 React.Component 和条件类型化道具时类型推断失败