How to mock the tricky things with Jest

Clint Goodman
3 min readFeb 3, 2022

Here are 3 scenarios that I have found tricky to mock in Jest, and how I solved these problems. This article is about mocking, not about writing meaningful tests, so please don’t get caught up in the arbitrary test cases themselves.

I will only make a few comments. Most of the power comes from studying these code examples to see what is going on.

Example 1 — Mocking imported constants by using lazy getters

I’ve been stuck in this situation many times before:

// app.js
import { someFunction, SOME_CONSTANT } from './someModule'
export default function doSomething(){
if (SOME_CONSTANT)
someFunction('abc')
else
someFunction('xyz')
}
// app.test.js
import doSomething from './app'
jest.mock('./someModule', () => ({
someFunction: jest.fn(),
SOME_CONSTANT: true,
}))
test.todo('when SOME_CONSTANT is true, this happens')// How do we set up this scenario within this same test suite?
test.todo('when SOME_CONSTANT is false, this happens')

We just assigned SOME_CONSTANT to be true for the whole test suite. How can we test when it is false? Most people don’t — they give up, and don’t write the second test case.

This is where I suggest a study of this simple lazy getter approach:

Notes:

  • Remember, this article is not about good code practices. These examples should tell your brain that the application code could use dependency injection, and this would eliminate the problem presented — and that is true. However, should you need to write a test of this nature for any reason, this lazy getter approach is helpful.

Example 2 — “Mocking” constants by substituting them

I want to show an alternate solution to the problem above, and how to get away with mocking something which isn’t even imported:

Notes:

  • The idea here is that you can change the prop being passed to Router simply by catching the real call to Router, forwarding along the other props (like children), but passing your own prop for history instead. In this case, I simply call a mock that can return an object, which allows me to change what object gets passed in each test by changing the mock implementation. I won’t say much more about this, just study it a little closer, and appreciate the simple genius of it.

Example 3 — Testing hooks

This is nothing fancy or new, but this is a pattern I’ve been using frequently. There are some cool npm packages just for testing hooks, which you can check out if you have advanced cases. But, 9/10 times for me, these few lines of code get the job done:

Notes:

  • Notice the 3rd argument of jest.spyOn, and how to mock a read-only attribute like an element’s offsetWidth.

Summary

These are the answers I wish I would have found when I tried to Google some of the following things:

  • “How to mock a constant in Jest”
  • “How to mock an element’s offsetHeight, offsetWidth, or other read-only attributes with Jest”
  • “How to partially mock with Jest”
  • “How to test the return value of a hook”

If these examples helped you learn a new idea, please share it in a comment!

--

--