0

我有一个简单的 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 组件。我该如何测试呢?

4

0 回答 0