Jest Mock: mock external file/lib method in test cases
Introduction
In your react project, you may have used some external libraries or file method for developing some functionalities. So when you try to test this particular functionality that you have developed, you get stuck trying to understand how to test this external method(s) (from npm libs) which are are being imported and used. I know this because, I was stuck in similar situation and the official jest docs had a lot of things in it but it was not specific enough to make me understand and it took me some time to wrap my head around this concept. This particular article is my solution to try and mock a particular external method (using jest mock method) in the test case for a simple example app. Hope this article saves time for a lot of fellow devs in the community!
Prerequisites
Before we start, I am assuming you know how to setup a react project, develop your functional component using react js and write basic test cases in react using JEST and enzyme. If not, there is definitely a ton of youtube videos, udemy courses, articles etc. on the internet to get familiar with it.
This article is focusing just on the one hurdle i.e HOW TO USE JEST.MOCK?!
The application
For the sake of this article, I have used typescript and my react project and for writing test cases I am using JEST and enzyme. The application that I have developed is a simple app that calculates age when you input your date of birth.

so the main logic is written in app.jsx which is as follows:
import React, { useState } from "react"; | |
import "./styles.css"; | |
import moment from "moment"; | |
export default function App() { | |
const [date, setDate] = useState(""); | |
const [age, setAge] = useState(0); | |
const calculateAge = () => { | |
console.log('diff called'); | |
const calcAge = moment().diff(date, "years"); | |
setAge(calcAge); | |
}; | |
return ( | |
<div className="App"> | |
<h2>How old are you?</h2> | |
<label>Birthday: </label> | |
<input | |
type="date" | |
onChange={(e) => setDate(e.target.value)} | |
value={date} | |
id="birthday" | |
name="birthday" | |
/> | |
<button disabled={!date.length} onClick={calculateAge}> | |
Calculate Age | |
</button> | |
<div>Your age is: {age}</div> | |
</div> | |
); | |
} |
Test cases
once we have the app file ready, we can start writing the test cases. I have written the following test cases:
- The application should render as expected
- the button should be disabled when the date is not picked
- once the date is picked the button should not be disabled
- moment library function is called it should be called with the given mock params
The jest test cases for the for above mentioned cases should look as follows:
import { shallow, configure } from "enzyme"; | |
import React from "react"; | |
import App from "../App"; | |
import Adapter from 'enzyme-adapter-react-16'; | |
//define mock for moment lib | |
const diff = jest.fn(); | |
const momentObj = () => ({ | |
diff | |
}) | |
jest.mock('moment', () => momentObj) | |
configure({ adapter: new Adapter() }); | |
describe("App", () => { | |
let wrapper; | |
beforeEach(() => { | |
wrapper = shallow(<App />); | |
}); | |
it("should render properly", () => { | |
expect(wrapper).toMatchSnapshot(); | |
}); | |
it('should have calculate button disabled, if date is not selected', () => { | |
const calcButton = wrapper.find('button').at(0); | |
expect(calcButton.prop('disabled')).toBe(true); | |
}); | |
it('should have calculate button enabled after date is selected', () => { | |
const picker = wrapper.find('input').at(0); | |
picker.prop('onChange')({ | |
target: { | |
value: '1990-10-02' | |
} | |
}); | |
const calcButton = wrapper.find('button').at(0); | |
expect(calcButton.prop('disabled')).toBe(false); | |
}); | |
it('should execute moment method to calculate age on button click', () => { | |
const moment = require('moment'); | |
const picker = wrapper.find('input').at(0); | |
picker.prop('onChange')({ | |
target: { | |
value: '1990-10-02' | |
} | |
}); | |
const calcButton = wrapper.find('button').at(0); | |
calcButton.prop('onClick')(); | |
expect(diff).toHaveBeenCalled(); | |
}) | |
}); |
Once we have the app spec/test file ready, we can just run the test command and run the test cases. It should show the following result:

What is happening
Let’s break down what’s happening in these test cases that we have defined. So the first 2-3 test cases are basic normal test cases nothing fancy we are just checking if the application is working as expected, the button should be disabled if the date is not picked and should not be disabled otherwise.
The final test case, however, we need to check whether a particular library’s i.e moment JS (which we know component uses internally) function/method has been called or not and if it is called is it called with the expected params. this particular case is crucial for the overall coverage of the application code that we have developed!

Before we start our mock, now we need to analyse and understand what moment JS class/method/function we are importing. We will focus the method we care about (our test case’s context) and we will mock that in our test case.
In our case, we have imported a function called moment which returns an object that contains the key value pair (diff) we are looking for.

Userful Links
- Code Sandbox: https://codesandbox.io/s/fancy-flower-orm9t?file=/src/App.tsx
- Github: https://github.com/ovpv/typescript-jest-mock
Conclusion
once you understand how the moment library’s (or any libraries or files for that matter) object and the function return works, you can easily mock it and create our mock object for your test case.
Jest.Mock can be used similarly in various scenario where you don’t have access to the the method/function/class which is used by the file you are testing/ writing test cases for!
Hope this article has generated some value and solved your doubts related to mocking methods using Jest.mock. If not, you can comment your doubts below and we can have a conversation on it.
6
You must be logged in to post a comment.