Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock a function from another file - Jest

Tags:

I am writing Unit test cases for my application. There is one function which is written in Utils section and Used in all files. I wanted to mock this Utils function whenever I need but I am unable to do so.

Here is my code setup:

Utils.js

> const getData = (name) => "Hello !!! " + name; >  > const getContact = ()=> return Contacts.mobile; >  > export { >     getData, >     getContact } 

Login.js (Which uses Utils.js)

    const welcomeMessage = (name) => {      return getData(name);     } 

My Test file (Login.spec.js)

import { getData } from '../../src/utils';   jest.mock('getData', () => jest.fn())   describe('User actions', () => {      it('should get username', () => {         const value = 'Hello !!! Jest';         expect(welcomeMessage('Jest')).toEqual(value);     });  }); 

When I run my test case then I am getting this error:

 Cannot find module 'getData' from 'Login.spec.js' 

I tried to find the solution on official Jest Documentation and on SO as well but couldn't found anything. I am unable to fix this error and mock this function.

like image 662
Rahul Avatar asked Mar 19 '18 09:03

Rahul


People also ask

How do you mock a function in another Jest?

To change the mock implementation of a function with Jest we use the mockImplementation() method of the mocked function. The mockImplementation() method is called with the new implementation as its argument. The new implementation will then be used in place of the previous one when the mock is called.

How do you mock a Jest file?

Note: In order to mock properly, Jest needs jest. mock('moduleName') to be in the same scope as the require/import statement. Here's a contrived example where we have a module that provides a summary of all the files in a given directory. In this case, we use the core (built in) fs module.

How do you mock only one function from a module in Jest?

Another approach to mock a particular function from an imported module is to use the jest. spyOn function. The API for this function seems to be exactly what we need for our use case, as it accepts an entire module and the particular export that should be spied on.

How do you test a function is called in Jest?

To check if a component's method is called, we can use the jest. spyOn method to check if it's called. We check if the onclick method is called if we get the p element and call it.


2 Answers

The first argument of jest.mock(...) must be a module path:

jest.mock('../../src/utils'); 

because the utils module is your code, not a 3rd lib, so you must learn manual mock of jest: https://facebook.github.io/jest/docs/en/manual-mocks.html

if you had this file: src/utils.js

you can mock it by creating a file: src/__mocks__/utils.js

content of this file is the replication of the original but replace the implementation by getData = jest.fn()

on you test file, just call: jest.mock('../../src/utils'); at begin of file.

then when you're familiar with, you can call that function inside beforeEach() and call its counter jest.unmock('../../src/utils'); insider afterEach()

An easy way to think about it is that:

when you call jest.mock('../../src/utils');, it means you tell jest that:

hey if the running test meets the line require('../../src/utils'), don't load it, let load ../../src/__mocks__/utils.

like image 53
Khoa Avatar answered Oct 27 '22 11:10

Khoa


I got the same question and finally I find the solution. I post it here for the one who got the same issue.

Jest test file:

import * as utils from "./demo/utils"; import { welcomeMessage } from "./demo/login";  // option 1: mocked value const mockGetData = jest.spyOn(utils, "getData").mockReturnValue("hello");  // option 2: mocked function const mockGetData = jest.spyOn(utils, "getData").mockImplementation((name) => "Hello !!! " + name);  describe("User actions", () => {     it("should get username", () => {         const value = "Hello !!! Jest";         expect(welcomeMessage("Jest")).toEqual(value);     }); }); 

references: https://jestjs.io/docs/jest-object#jestfnimplementation

jest.spyOn(object, methodName)

Creates a mock function similar to jest.fn but also tracks calls to object[methodName]. Returns a Jest mock function.

Note: By default, jest.spyOn also calls the spied method. This is different behavior from most other test libraries. If you want to override the original function, you can use:

jest.spyOn(object, methodName).mockImplementation(() => customImplementation) 

or

object[methodName] = jest.fn(() => customImplementation); 
like image 34
sherwin water Avatar answered Oct 27 '22 12:10

sherwin water