Вот решение, вы можете смоделировать FormData
и ввести event
вручную:
index.tsx
:
import React, { Component } from 'react';
import console = require('console');
class XComponent extends Component {
constructor(props) {
super(props);
this.buildFormData = this.buildFormData.bind(this);
}
public buildFormData(event) {
event.preventDefault();
const { target } = event;
const data: any = new FormData(target);
if (target.querySelectorAll('.ant-select').length) {
const selectTags = target.querySelectorAll('.ant-select');
selectTags.forEach(selectTag => {
const value = selectTag.querySelector('.ant-select-selection-selected-value').getAttribute('title');
const property = selectTag.getAttribute('id');
data.append(property, value);
});
}
const getDataObject = {};
for (const pair of data.entries()) {
// Ensures that the data from the forms have a value
if (pair[1]) {
getDataObject[pair[0]] = pair[1];
}
}
return getDataObject;
}
public render() {
return (
<div>
<form onSubmit={this.buildFormData}></form>
</div>
);
}
}
export default XComponent;
index.spec.tsx
:
import React from 'react';
import XComponent from './';
import { shallow } from 'enzyme';
const FormDataMock = {
append: jest.fn(),
entries: jest.fn()
};
describe('XComponent', () => {
const mockedFormEvent = { target: { querySelectorAll: jest.fn() }, preventDefault: jest.fn() };
beforeEach(() => {
(global as any).FormData = jest.fn(() => FormDataMock);
});
afterEach(() => {
jest.resetAllMocks();
});
it('should build form data correctly without select tags', () => {
mockedFormEvent.target.querySelectorAll.mockReturnValueOnce([]);
FormDataMock.entries.mockReturnValueOnce([['k1', 'v1'], ['k2', 'v2'], ['k3', 'v3']]);
const wrapper = shallow(<XComponent></XComponent>);
const actualValue = (wrapper.instance() as any).buildFormData(mockedFormEvent);
expect(actualValue).toEqual({ k1: 'v1', k2: 'v2', k3: 'v3' });
expect(mockedFormEvent.preventDefault).toBeCalledTimes(1);
expect(mockedFormEvent.target.querySelectorAll).toBeCalledWith('.ant-select');
expect((global as any).FormData).toBeCalledTimes(1);
});
it('should build form data correctly with select tags', () => {
const mockedSelectTag = { querySelector: jest.fn().mockReturnThis(), getAttribute: jest.fn() };
const mockedSelectTags = [mockedSelectTag];
(mockedSelectTag.querySelector().getAttribute as any).mockReturnValueOnce('value').mockReturnValueOnce('property');
mockedFormEvent.target.querySelectorAll.mockReturnValue(mockedSelectTags);
FormDataMock.entries.mockReturnValueOnce([['k1', 'v1'], ['k2', 'v2'], ['k3', 'v3']]);
const wrapper = shallow(<XComponent></XComponent>);
const actualValue = (wrapper.instance() as any).buildFormData(mockedFormEvent);
expect((global as any).FormData).toBeCalledTimes(1);
expect(actualValue).toEqual({ k1: 'v1', k2: 'v2', k3: 'v3' });
expect(FormDataMock.append).toBeCalledWith('property', 'value');
expect(mockedFormEvent.preventDefault).toBeCalledTimes(1);
expect(mockedFormEvent.target.querySelectorAll).toBeCalledWith('.ant-select');
});
});
Результат модульного теста с отчетом о покрытии:
PASS src/stackoverflow/58136380/index.spec.tsx (5.601s)
XComponent
✓ should build form data correctly without select tags (11ms)
✓ should build form data correctly with select tags (3ms)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 100 | 83.33 | 100 | 100 | |
index.tsx | 100 | 83.33 | 100 | 100 | 27 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 10.438s, estimated 15s
Исходный код: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58136380