我有一个简单的 React 组件,它使用了“redux-form”库中的 FieldArray,我很难增加该组件的测试覆盖率。当我控制台记录组件时,我得到了一个ConnectedFieldArray
组件,但不完全确定如何测试它。
AMLScreeningSummary.js
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'xps-react';
import { FieldArray } from 'redux-form';
// Components
import SectionBox from '../../common/Fields/SectionBox';
import AMLScreeningRowFields from './AMLScreeningRowFields';
// Constants
import { TABLE_HEADER } from '../../../constants/DataAttributes/amlScreeningSummary';
// Styles
import './style.scss';
export default class AMLScreeningSummary extends Component {
static propTypes = {
attributeList: PropTypes.array,
label: PropTypes.string,
isQC: PropTypes.bool,
isReadOnly: PropTypes.bool,
diff: PropTypes.any
};
static defaultProps = {
isQC: false,
isReadOnly: false,
diff: []
};
constructor(props) {
super(props);
this.renderPreScreeningRows = this.renderPreScreeningRows.bind(this);
}
renderPreScreeningField(fieldConfiguration, preScreeningDetailName, rowIndex, formName) {
return (
<AMLScreeningRowFields
key={`${preScreeningDetailName}_${fieldConfiguration.id}`}
formName={formName}
rowName={preScreeningDetailName}
rowIndex={rowIndex}
fieldAttr={fieldConfiguration}
isQC={this.props.isQC}
isReadOnly={this.props.isReadOnly}
diff={this.props.diff}
/>
);
}
renderPreScreeningRows({ fields, meta }) {
return fields.map((preScreeningDetailName, rowIndex) => (
<Fragment key={`${preScreeningDetailName}`}>
<hr className="margintop-lg marginbottom-xl" />
<Row>
{this.props.attributeList.map(fieldGroupingConfiguration => {
const { columnSize, fieldsConfiguration, id } = fieldGroupingConfiguration;
return (
<Col key={`${preScreeningDetailName}_${id}`} sm={columnSize}>
<Row>
{fieldsConfiguration.map(fieldConfiguration =>
this.renderPreScreeningField(fieldConfiguration, preScreeningDetailName, rowIndex, meta.form)
)}
</Row>
</Col>
);
})}
</Row>
</Fragment>
));
}
render() {
return (
<SectionBox sectionClassName="aml-screening-summary" label={this.props.label}>
<Row>
{Object.keys(TABLE_HEADER).map(columnGrouping => (
<Col key={TABLE_HEADER[columnGrouping].id} sm={TABLE_HEADER[columnGrouping].columnSize}>
<Row>
{Object.keys(TABLE_HEADER[columnGrouping].subColumns).map(subColumn => (
<Col
key={TABLE_HEADER[columnGrouping].subColumns[subColumn].id}
sm={TABLE_HEADER[columnGrouping].subColumns[subColumn].size}
>
<strong>{TABLE_HEADER[columnGrouping].subColumns[subColumn].label}</strong>
</Col>
))}
</Row>
</Col>
))}
</Row>
<FieldArray
component={this.renderPreScreeningRows}
attributeList={this.props.attributeList}
name="partyRoleAML.preScreeningDetailArray"
/>
</SectionBox>
);
}
}
AMLScreeningSummary.test.js
import React from 'react';
import { mount } from 'enzyme';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import { reducer as form, reduxForm, FieldArray } from 'redux-form';
import AMLScreeningSummary from '../../../../src/components/FormSections/AMLScreeningSummary/AMLScreeningSummary';
import SectionBox from '../../../../src/components/common/Fields/SectionBox';
const mockStore = configureMockStore([]);
const data = {
label: 'Component - AML Screening Summary',
attributeList: [
{
columnSize: 1,
id: 'category',
mapping: 'preScreeningTyp',
type: 'staticDisplayText'
},
{
columnSize: 2,
id: 'result',
mapping: 'cnfmdTyp',
type: 'dropdown',
typeCategoryName: 'ConfirmedType'
},
{
className: 'amResultCategory',
columnSize: 1,
id: 'resultCategory',
label: 'Category',
mapping: 'screeningCtgryTyp',
offsetRight: 1,
type: 'dropdown',
typeCategoryName: 'ScreeningCategoryType'
}
],
isQC: true
};
const formData = {
initialValues: {
partyRoleAML: {
preScreeningDetailArray: [{ preScreeningDetailName: 'test', mnlRskRtTyp: 'test', overrideRiskRating: 'test' }]
}
},
form: 'testForm'
};
describe(' AML Screening Summary ', () => {
let wrapper;
let store;
beforeEach(() => {
const AMLScreeningSummaryWithForm = reduxForm(formData)(AMLScreeningSummary);
store = mockStore({ form });
wrapper = mount(
<Provider store={store}>
<AMLScreeningSummaryWithForm
formName="testForm"
form="testForm"
label={data.label}
attributeList={data.attributeList}
isQC
/>
</Provider>
);
});
it('Should have Section length one', () => {
console.log(wrapper.debug());
expect(wrapper.find(SectionBox)).toHaveLength(1);
});
it('Should have Row length one', () => {
const fieldArray = wrapper.find(FieldArray);
expect(wrapper.find(FieldArray)).toHaveLength(1);
const ConnectedFieldArray = wrapper.find('ConnectedFieldArray');
});
});
这是 console.log(wrapper.debug()) 的输出
<Provider store={{...}}>
<ReduxForm formName="testForm" form="testForm" label="Component - AML Screening Summary" attributeList={{...}} isQC={true}>
<Connect(Form(AMLScreeningSummary)) formName="testForm" form="testForm" label="Component - AML Screening Summary" attributeList={{...}} isQC={true} initialValues={{...}} touchOnBlur={true} touchOnChange={false} persistentSubmitErrors={false} destroyOnUnmount={true} shouldAsyncValidate={[Function: defaultShouldAsyncValidate]} shouldValidate={[Function: defaultShouldValidate]} shouldError={[Function: defaultShouldError]} shouldWarn={[Function: defaultShouldWarn]} enableReinitialize={false} keepDirtyOnReinitialize={false} updateUnregisteredFields={false} getFormState={[Function: getFormState]} pure={true} forceUnregisterOnUnmount={false}>
<Form(AMLScreeningSummary) formName="testForm" form="testForm" label="Component - AML
Screening Summary" attributeList={{...}} isQC={true} initialValues={{...}} touchOnBlur={true} touchOnChange={false} persistentSubmitErrors={false} destroyOnUnmount={true} shouldAsyncValidate={[Function: defaultShouldAsyncValidate]} shouldValidate={[Function: defaultShouldValidate]} shouldError={[Function: defaultShouldError]} shouldWarn={[Function: defaultShouldWarn]} enableReinitialize={false} keepDirtyOnReinitialize={false} updateUnregisteredFields={false} getFormState={[Function: getFormState]} pure={true} forceUnregisterOnUnmount={false} anyTouched={false} asyncErrors={[undefined]} asyncValidating={false} dirty={false} error={[undefined]} initialized={false} invalid={false} pristine={true} registeredFields={[undefined]} submitting={false} submitFailed={false} submitSucceeded={false} syncErrors={{...}} syncWarnings={{...}} triggerSubmit={[undefined]} values={{...}} valid={true} validExceptSubmit={true} warning={[undefined]} autofill={[Function (anonymous)]} clearFields={[Function (anonymous)]} clearSubmit={[Function (anonymous)]} clearSubmitErrors={[Function (anonymous)]} clearAsyncError={[Function (anonymous)]} destroy={[Function
(anonymous)]} initialize={[Function (anonymous)]} registerField={[Function (anonymous)]} reset={[Function (anonymous)]} resetSection={[Function (anonymous)]} startAsyncValidation={[Function (anonymous)]} startSubmit={[Function (anonymous)]} stopAsyncValidation={[Function (anonymous)]} stopSubmit={[Function (anonymous)]} submit={[Function (anonymous)]} setSubmitFailed={[Function (anonymous)]} setSubmitSucceeded={[Function (anonymous)]} touch={[Function (anonymous)]} unregisterField={[Function (anonymous)]} untouch={[Function (anonymous)]} updateSyncErrors={[Function (anonymous)]} updateSyncWarnings={[Function (anonymous)]} arrayInsert={[Function: bound arrayInsert]} arrayMove={[Function: bound arrayMove]} arrayPop={[Function: bound arrayPop]} arrayPush={[Function: bound arrayPush]} arrayRemove={[Function: bound arrayRemove]} arrayRemoveAll={[Function: bound arrayRemoveAll]} arrayShift={[Function: bound arrayShift]} arraySplice={[Function: bound arraySplice]} arraySwap={[Function: bound arraySwap]} arrayUnshift={[Function: bound arrayUnshift]} blur={[Function: boundBlur]} change={[Function: boundChange]} array={{...}} focus={[Function:
bound focus]} dispatch={[Function: dispatch]}>
<AMLScreeningSummary array={{...}} anyTouched={false} asyncValidate={[Function (anonymous)]} asyncValidating={false} blur={[Function (anonymous)]} change={[Function (anonymous)]} clearSubmit={[Function (anonymous)]} destroy={[Function (anonymous)]} dirty={false} dispatch={[Function: dispatch]} error={[undefined]} form="testForm" handleSubmit={[Function (anonymous)]} initialize={[Function (anonymous)]} initialized={false} initialValues={{...}} invalid={false} pristine={true} reset={[Function (anonymous)]} resetSection={[Function (anonymous)]} submitting={false} submitFailed={false} submitSucceeded={false} touch={[Function (anonymous)]} untouch={[Function (anonymous)]} valid={true} warning={[undefined]} formName="testForm" label="Component - AML Screening Summary" attributeList={{...}} isQC={true} pure={true} triggerSubmit={[undefined]} autofill={[Function (anonymous)]} clearFields={[Function (anonymous)]} clearSubmitErrors={[Function (anonymous)]} clearAsyncError={[Function (anonymous)]} submit={[Function (anonymous)]} isReadOnly={false} diff={{...}}>
<SectionBox sectionClassName="aml-screening-summary" label="Component - AML Screening Summary">
<div className="section-box-content-container aml-screening-summary">
<Row>
<div className="row">
<Col sm={5}>
<div className="col-sm-5">
<Row>
<div className="row">
<Col sm={2}>
<div className="col-sm-2">
<strong>
Category
</strong>
</div>
</Col>
<Col sm={10}>
<div className="col-sm-10">
<strong>
Result
</strong>
</div>
</Col>
</div>
</Row>
</div>
</Col>
<Col sm={7}>
<div className="col-sm-7">
<Row>
<div className="row">
<Col sm={1}>
<div className="col-sm-1">
<strong>
Discount
</strong>
</div>
</Col>
<Col sm={2}>
<div className="col-sm-2">
<strong>
Discount By
</strong>
</div>
</Col>
<Col sm={8}>
<div className="col-sm-8">
<strong>
Discount Reason
</strong>
</div>
</Col>
</div>
</Row>
</div>
</Col>
</div>
</Row>
<FieldArray component={[Function: bound renderPreScreeningRows]} attributeList={{...}} name="partyRoleAML.preScreeningDetailArray">
<Connect(ConnectedFieldArray) component={[Function: bound renderPreScreeningRows]} attributeList={{...}} name="partyRoleAML.preScreeningDetailArray" _reduxForm={{...}}>
<ConnectedFieldArray component={[Function: bound renderPreScreeningRows]}
attributeList={{...}} name="partyRoleAML.preScreeningDetailArray" _reduxForm={{...}} asyncError={[undefined]} dirty={true} pristine={false} state={[undefined]} submitError={[undefined]} submitFailed={[undefined]} submitting={[undefined]} syncError={[undefined]} syncWarning={[undefined]}
value={[undefined]} length={0} arrayInsert={[Function (anonymous)]} arrayMove={[Function (anonymous)]} arrayPop={[Function (anonymous)]} arrayPush={[Function (anonymous)]} arrayRemove={[Function (anonymous)]} arrayRemoveAll={[Function (anonymous)]} arrayShift={[Function (anonymous)]} arraySplice={[Function (anonymous)]} arraySwap={[Function (anonymous)]} arrayUnshift={[Function (anonymous)]} rerenderOnEveryChange={false}>
<bound renderPreScreeningRows fields={{...}} meta={{...}} attributeList={{...}} />
</ConnectedFieldArray>
</Connect(ConnectedFieldArray)>
</FieldArray>
</div>
</SectionBox>
</AMLScreeningSummary>
</Form(AMLScreeningSummary)>
</Connect(Form(AMLScreeningSummary))>
</ReduxForm>
</Provider>
如何测试 renderPreScreeningRows 和 renderPreScreeningField 函数返回的内容/子组件?console.log 语句显示它们是一个 ConnectedFieldArray 组件。我该如何测试呢?