Here is the solution:
index.tsx
:
import React from 'react';
import axios from 'axios';
export class SomeComponent extends React.Component {
constructor(props) {
super(props);
this.handleLogout = this.handleLogout.bind(this);
}
public render() {
return (
<div>
<button type="button" value="Logout" onClick={this.handleLogout}>
Logout
</button>
</div>
);
}
private handleLogout(event: React.MouseEvent<HTMLButtonElement>) {
event.preventDefault();
axios
.post('/logout')
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
}
}
Unit test:
index.spec.tsx
:
import React from 'react';
import { shallow } from 'enzyme';
import axios from 'axios';
import { SomeComponent } from './';
jest.mock('axios', () => {
return {
post: jest.fn()
};
});
describe('SomeComponent', () => {
describe('#handleLogout', () => {
const mockedMouseEvent = {
preventDefault: jest.fn()
};
it('should logout correctly', done => {
const mockedData = 'mocked data';
const wrapper = shallow(<SomeComponent></SomeComponent>);
expect(wrapper.find('button')).toHaveLength(1);
(axios.post as jest.MockedFunction<typeof axios.post>).mockResolvedValueOnce(mockedData);
const consoleLogSpyOn = jest.spyOn(console, 'log');
wrapper.find('button').simulate('click', mockedMouseEvent);
expect(wrapper.find('button').text()).toBe('Logout');
expect(axios.post).toBeCalledWith('/logout');
setImmediate(() => {
expect(consoleLogSpyOn).toBeCalledWith(mockedData);
consoleLogSpyOn.mockRestore();
done();
});
});
it('should throw error when axios post error', done => {
const mockedError = new Error('network error');
const wrapper = shallow(<SomeComponent></SomeComponent>);
expect(wrapper.find('button')).toHaveLength(1);
(axios.post as jest.MockedFunction<typeof axios.post>).mockRejectedValueOnce(mockedError);
const consoleLogSpyOn = jest.spyOn(console, 'log');
wrapper.find('button').simulate('click', mockedMouseEvent);
expect(wrapper.find('button').text()).toBe('Logout');
expect(axios.post).toBeCalledWith('/logout');
setImmediate(() => {
expect(consoleLogSpyOn).toBeCalledWith(mockedError);
consoleLogSpyOn.mockRestore();
done();
});
});
});
});
Unit test result with 100% coverage:
PASS src/stackoverflow/54555039/index.spec.tsx
SomeComponent
#handleLogout
✓ should logout correctly (29ms)
✓ should throw error when axios post error (14ms)
console.log node_modules/jest-mock/build/index.js:860
mocked data
console.log node_modules/jest-mock/build/index.js:860
Error: network error
at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/54555039/index.spec.tsx:36:27)
at resolve (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
at new Promise (<anonymous>)
at mapper (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
at promise.then (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.tsx | 100 | 100 | 100 | 100 | |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 4.483s, estimated 5s
Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/54555039