JEST (HOW TO MOCK)
Tags: react, javascript, testing
Published: 2020-07-18 19:34:14


###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

```javascript
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.

```javascript
  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.

```javascript
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.

```javascript
     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

```javascript
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

```javascript
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

```javascript
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 
```javascript
tree.instance().refs = {target:something}
```

Example:- 
```javascript
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

```javascript
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:-
```javascript
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-
```javascript
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.