我想测试一个返回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()。请查看我在 render 函数中如何调用它,例如产品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" />
任何建议都值得赞赏。
答案 0 :(得分:0)
如我所见,您的代码有两个问题:
您无意中调用了expect
中的模拟函数,这会导致错误:expect
正在接收模拟iconRenderer
的返回值,而不是模拟本身。将您的expect
行更改为:
expect(wrapper.instance().iconRenderer).toHaveBeenCalled();
您需要在渲染iconRenderer
之前模拟Product
,因此在渲染Product
时会调用它。因此,需要在此行之前对其进行模拟:
const wrapper = shallow(<Products {...props} />);
您可以在this question中看到有关此操作的示例。