loading...
Cover image for JEST (HOW TO MOCK)

JEST (HOW TO MOCK)

shandilyaprasanna profile image Prasanna Shandilya ・3 min read

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 by:

shandilyaprasanna profile

Prasanna Shandilya

@shandilyaprasanna

I am a JS developer with industry experience in OTT and E-commerce domain building websites, web applications and PWA. I specialize in JavaScript with experience in react, node.

Discussion

markdown guide