JEST (HOW TO MOCK)
Prasanna Shandilya
Posted on July 18, 2020
What is Mock?
According to Jest documentation:-
Mock functions make it easy to test the links between code by erasing the actual implementation of a function, capturing calls to the function (and the parameters passed in those calls).
Lets Mock now:-
1.) Mock Functions
const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();
2.) Mock function to return value (mockReturnValue , mockImplementation)
You can provide a value to be returned by the mock by calling the mockReturnValue() function.
const mockFn = jest.fn();
myMock.mockReturnValue("hello");
expect(mockFn()).toBe("hello");
With mockReturnValue it does not matter what arguments you are passing to it,
but in some cases, it may be useful to return a value from your mock, based on arguments given to it. This can be achieved by mockImplementation() function.
let store = {}
jest.fn().mockImplementation((key, value) => {
store[key] = value;
}),
3.) Mock Fetch call
You can also mock the implementation for asynchronous functions. In this case, just return a promise from the implementation.
global.fetch = jest.fn().mockImplementation(() =>
Promise.resolve({
status:200,
statusText:"success",
json: () => {
return { ok: true, result:data, }; // return result which you expect from api
}
})
);
4.) Mock imported file
There may be a case where your component is importing some other modules or icons but you don't want to handle it.
In that case, mock the whole path to return a string
jest.mock("file/pathname", () => "Module");
5.) JEST Mock Imported Function from different file
Let's combine above two points, a situation where you are making an async call in the imported file
import * as utils from "./LoginUtils";
utils.postToLogin = jest.fn().mockImplementation(() =>{
let userLogin=new Promise((resolve, reject)=>{
return resolve({status:"OK"})
})
return userLogin;
}
);
6.) Mock localStorage, sessionstorage, cookie
Using mockImplementation you can also mock localstorage
let store = {};
global.localStorage = {
setItem: jest.fn().mockImplementation((key, value) => {
JSON.stringify((store[key] = value));
}),
getItem: jest.fn().mockImplementation(key => store[key])
};
7.) Mock REFS
First, create an instance of your component, then we can mock refs by
tree.instance().refs = {target:something}
Example:-
const instance_refs = tree.instance();
let mockFunction=jest.fn();
instance_refs.refs = {
yourRefName:{getWrappedInstance:()=>{return({changePaginationDetails:mockFunction})}}
};
instance_refs.changeCurrentPage();
8.) setTimeout, setInterval, clearTimeout, clearInterval
Jest provides us with timer functions useFakeTimers and runAllTimers to mock timers
jest.useFakeTimers();
test('waits for timer', () => {
jest.runAllTimers();
expect(something).toHaveBeenCalled();
});
9.) How to mock react portal (Example to test modal )
Let's test the modal component created using the React portal. this modal mounts to a dom node on the root of the "body"
Modal code:-
import React from "react";
import ReactDOM from "react-dom";
export default props => {
const domNode = document.getElementById("fullPageModal");
const modal = <div className="fullPageModal">{props.children}</div>;
return ReactDOM.createPortal(modal, domNode);
};
First, we need to add a div with #fullPageModal id to the global body
Test-
describe("FullPageModal component", () => {
let component;
const Child = () => <div>Yolo</div>;
// add a div with #fullPageModal id to the global body
const modalRoot = global.document.createElement("div");
modalRoot.setAttribute("id", "fullPageModal");
const body = global.document.querySelector("body");
body.appendChild(modalRoot);
beforeEach(() => {
component = mount(
<FullPageModal>
<Child />
</FullPageModal>
);
});
it("should render Modal, on dom node fullPageModal", () => {
const domNode = global.document.getElementById("fullPageModal");
expect(component.find(".fullPageModal").exists()).to.equal(true);
});
});
Please share your experience also where you have mocked something, would love to read it.
Posted on July 18, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.