Вот решение для модульного тестирования:
index.tsx
:
import React, { Component } from 'react';
import * as templateService from './templateService';
class SomeComponent extends Component {
constructor(props) {
super(props);
this.state = {
errors: {
api: '',
},
};
}
downloadExcel = () => {
templateService.getTemplate().then(
(response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'Project_register_template_PMB.xlsx');
document.body.appendChild(link);
link.click();
},
(error) => {
this.setState({
errors: { api: `API error:${error}, please contact an administrator` },
});
},
);
};
render() {
return <button onClick={() => this.downloadExcel()}>Download</button>;
}
}
export default SomeComponent;
templateService.ts
:
export const getTemplate = async () => {
return { data: 'real data' };
};
index.test.ts
:
import SomeComponent from './';
import React from 'react';
import { mount, ReactWrapper, shallow } from 'enzyme';
import * as templateService from './templateService';
import { act } from 'react-dom/test-utils';
const whenStable = async () => {
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 0));
});
};
describe('59715038', () => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<SomeComponent></SomeComponent>);
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('#downloadExcel', () => {
it('should download excel correctly', async () => {
const url = 'https://github.com';
const mResponse = { data: 'fake data' };
jest.spyOn(templateService, 'getTemplate').mockResolvedValueOnce(mResponse);
window.URL.createObjectURL = jest.fn().mockReturnValueOnce(url);
const mLink = { href: '', setAttribute: jest.fn(), click: jest.fn() };
document.createElement = jest.fn().mockReturnValueOnce(mLink);
document.body.appendChild = jest.fn();
wrapper.find('button').simulate('click');
await whenStable();
expect(window.URL.createObjectURL).toBeCalledWith(new Blob([mResponse.data]));
expect(document.createElement).toBeCalledWith('a');
expect(mLink.href).toBe(url);
expect(mLink.setAttribute).toBeCalledWith('download', 'Project_register_template_PMB.xlsx');
expect(document.body.appendChild).toBeCalledWith(mLink);
expect(mLink.click).toBeCalledTimes(1);
});
it('should set errors if get template failure', async () => {
const mError = new Error('some error');
jest.spyOn(templateService, 'getTemplate').mockRejectedValueOnce(mError);
wrapper.find('button').simulate('click');
await whenStable();
expect(wrapper.state()).toEqual({ errors: { api: `API error:${mError}, please contact an administrator` } });
});
});
});
Результаты модульных испытаний с отчетом о покрытии:
PASS src/stackoverflow/59715038/index.test.tsx (5.098s)
59715038
#downloadExcel
✓ should download excel correctly (30ms)
✓ should set errors if get template failure (12ms)
--------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
--------------------|----------|----------|----------|----------|-------------------|
All files | 91.67 | 100 | 87.5 | 95 | |
index.tsx | 100 | 100 | 100 | 100 | |
templateService.ts | 33.33 | 100 | 0 | 50 | 2 |
--------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 8.485s
Исходный код: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59715038