Вот решение, вы можете использовать .simulate(event[, ...args])
метод enzyme
для запуска реакции dom SyntheticEvent .Документы: https://airbnb.io/enzyme/docs/api/ShallowWrapper/simulate.html
Например:
index.tsx
:
import React, { Component } from 'react';
export interface ISomeComponentState {
firstName: string;
lastName: string;
isDone: boolean;
[key: string]: any;
}
export class SomeComponent extends Component<any, ISomeComponentState> {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: '',
isDone: false
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
}
public render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
firstName:
<input
type="text"
name="firstName"
placeholder="enter your first name"
value={this.state.firstName}
onChange={this.handleInputChange}
/>
</label>
<label>
lastName:
<input
type="text"
name="lastName"
placeholder="enter your last name"
value={this.state.lastName}
onChange={this.handleInputChange}
/>
</label>
<div>
<input type="submit" value="Submit" />
</div>
</form>
</div>
);
}
private handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
const target = event.target;
const name = target.name;
const value = target.value;
this.setState({ [name]: value });
}
private handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
this.setState({ isDone: true });
const nameMatch = () => {
return !(this.state.firstName.match('^Cel.*') && this.state.firstName.endsWith('on'));
};
if (nameMatch()) {
alert('Please enter a valid name');
return;
}
if (!this.state.lastName.endsWith('on')) {
alert('check lastname too');
return;
}
this.getFullName();
}
private getFullName() {
const { firstName, lastName } = this.state;
return firstName + ' ' + lastName;
}
}
index.spec.tsx
:
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { SomeComponent, ISomeComponentState } from './';
describe('SomeComponent', () => {
let wrapper: ShallowWrapper;
let getFullNameSpy;
let alertSpy;
beforeEach(() => {
alertSpy = jest.spyOn(window, 'alert');
getFullNameSpy = jest.spyOn(SomeComponent.prototype as any, 'getFullName');
wrapper = shallow(<SomeComponent></SomeComponent>);
});
afterEach(() => {
jest.resetAllMocks();
});
it('check submit', () => {
expect(wrapper.find('form')).toHaveLength(1);
const formEventMocked = { preventDefault: jest.fn() };
const state: ISomeComponentState = {
firstName: 'Cel.du.on',
lastName: 'lin.on',
isDone: false
};
wrapper.setState(state);
expect(wrapper).toMatchSnapshot();
wrapper.find('form').simulate('submit', formEventMocked);
expect(getFullNameSpy).toBeCalledTimes(1);
expect(formEventMocked.preventDefault).toBeCalledTimes(1);
expect(wrapper.state('isDone')).toBeTruthy();
});
it('should alert when first name is invalid', () => {
expect(wrapper.find('form')).toHaveLength(1);
const formEventMocked = { preventDefault: jest.fn() };
const state: ISomeComponentState = {
firstName: 'du',
lastName: 'lin.on',
isDone: false
};
wrapper.setState(state);
expect(wrapper).toMatchSnapshot();
wrapper.find('form').simulate('submit', formEventMocked);
expect(alertSpy).toBeCalledWith('Please enter a valid name');
expect(formEventMocked.preventDefault).toBeCalledTimes(1);
expect(wrapper.state('isDone')).toBeTruthy();
});
it('should alert when last name is invalid', () => {
expect(wrapper.find('form')).toHaveLength(1);
const formEventMocked = { preventDefault: jest.fn() };
const state: ISomeComponentState = {
firstName: 'Cel.du.on',
lastName: 'lin',
isDone: false
};
wrapper.setState(state);
expect(wrapper).toMatchSnapshot();
wrapper.find('form').simulate('submit', formEventMocked);
expect(alertSpy).toBeCalledWith('check lastname too');
expect(formEventMocked.preventDefault).toBeCalledTimes(1);
expect(wrapper.state('isDone')).toBeTruthy();
});
});
Юнит-тест сотчет о покрытии:
PASS src/stackoverflow/58085900/index.spec.tsx
SomeComponent
✓ check submit (17ms)
✓ should alert when first name is invalid (8ms)
✓ should alert when last name is invalid (4ms)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 88.24 | 100 | 85.71 | 86.21 | |
index.tsx | 88.24 | 100 | 85.71 | 86.21 | 56,57,58,60 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 3 passed, 3 total
Time: 3.113s, estimated 8s
Вот демоверсия: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58085900