Reputation: 408
I have a React application, and I am using Jest and Enzyme for unit testing the application. I am using a third-party library that returns a callback function. I am struggling to complete code coverage for the code inside the callback function. I tried mocking and spyOn but couldn’t use it to my use case. Can I get any suggestions on how to approach this?
I have created a sample code for reference
https://codesandbox.io/s/xenodochial-kilby-obnmt
someLibrary.js
export function getUserContext(callback) {
var context = {
userName: "TestUser",
locale: "en-us"
};
callback(context);
}
MyApp.js
componentDidMount() {
someLib.getUserContext((context) => {
//want to cover these below lines
//and some other codes inside this callback function
this.setState({
userName: context.userName,
locale: context.locale
});
//some other code to cover
});
}
App.test.js - as of now
describe("App Component", () => {
const wrapper = shallow(<App />);
//const layout = wrapper.instance();
it("renders the component", () => {
expect(wrapper.exists()).toBe(true);
});
it("sets the user context", () => {
//not sure what to write here inorder to cover
});
});
Upvotes: 0
Views: 2112
Reputation: 102457
Use jest.spyOn(object, methodName) to overwrite the original someLib.getUserContext()
method, you can use jest.spyOn(object, methodName).mockImplementation(() => customImplementation)
.
So that you can get the callback function in customImplementation
function.
Invoke this callback function with mocked data.
E.g.
MyApp.jsx
:
import React, { Component } from 'react';
import * as someLib from './someLibrary';
export default class MyApp extends Component {
constructor() {
super();
this.state = {
userName: '',
locale: '',
};
}
componentDidMount() {
someLib.getUserContext((context) => {
this.setState({
userName: context.userName,
locale: context.locale,
});
});
}
render() {
const { userName } = this.state;
return <div>{userName}</div>;
}
}
MyApp.test.jsx
:
import React from 'react';
import { shallow } from 'enzyme';
import App from './MyApp';
import * as someLib from './someLibrary';
describe('App Component', () => {
it('renders the component', () => {
const wrapper = shallow(<App />);
expect(wrapper.exists()).toBe(true);
});
it('sets the user context', () => {
const getUserContextSpy = jest.spyOn(someLib, 'getUserContext').mockImplementation((callback) => {
callback({ userName: 'mocked user name', locale: 'zh_CN' });
});
const wrapper = shallow(<App />);
expect(wrapper.text()).toEqual('mocked user name');
expect(getUserContextSpy).toBeCalledWith(expect.any(Function));
});
});
test result:
PASS examples/68102090/MyApp.test.jsx (12.251 s)
App Component
✓ renders the component (6 ms)
✓ sets the user context (2 ms)
----------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
MyApp.jsx | 100 | 100 | 100 | 100 |
someLibrary.js | 100 | 100 | 100 | 100 |
----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 14.305 s
Upvotes: 3