Mock Only a Single Function from a Module with Jest

Recall that using jest.mock(module) mocks every function exported from the module.

But sometimes we need to mock only one or some functions in a module, leaving the others’ real implementations as-is.

Suppose we are using the following module of functions:

my-functions.js:

const f = () => 'Return from f'
const g = () => 'Return from g'
const h = () => 'Return from h'

module.exports = {
  f,
  g,
  h
}

The code below uses a Jest spy with a mock implementation to mock out just one function while leaving alone the original implementations of the other two.

my-functions.test.js:

const functions = require('./my-functions')

describe('mock only one function from module', () => {
  it('should return only one mocked result', () => {
    jest.spyOn(functions, 'g')
      .mockImplementation(() => '_mock_')

    console.log(functions.f())
    console.log(functions.g())
    console.log(functions.h())

    expect(functions.f()).toEqual('Return from f')
    expect(functions.g()).toEqual('_mock_')
    expect(functions.h()).toEqual('Return from h')
  })
})

Running the tests:

$ jest my-functions.test.js
PASS ./my-functions.test.js
mock only one function from module
✓ should return only one mocked result (14ms)

console.log my-functions.test.js:8
Return from f

console.log my-functions.test.js:9
_mock_

console.log my-functions.test.js:10
Return from h

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.956s
Ran all test suites matching /my-functions.test.js/i.

Note that only g() returns a mocked string.

 

Jest Mock Behaviour with mockReturnValueOnce

A Jest mock function can be set to return a specific value for all calls, or just once.

Note that if we define a return value with mockReturnValueOnce, the mock function will return undefined for all subsequent calls.
It will not throw an error and may go unnoticed, causing undesirable behaviour.

If a Jest mock returns undefined incorrectly check to make sure how it was defined and how many times it was called.

The code below shows the different behaviours:

describe('mock once tests', () => {
  test('many returns', () => {
    const f = jest.fn()
    f.mockReturnValueOnce('result')

    const result1 = f()
    console.log(result1)

    const result2 = f()
    console.log(result2)

    const result3 = f()
    console.log(result3)
  })

  test('one return', () => {
    const f = jest.fn()
    f.mockReturnValue('result')

    const result1 = f()
    console.log(result1)

    const result2 = f()
    console.log(result2)

    const result3 = f()
    console.log(result3)
  })
})

Output:

result
undefined
undefined

result
result
result

 

Force Vagrant to Re-download the Box File

Sometimes we want to download the operating system image file again and start from scratch when building a Vagrant VM.

If vagrant up does not load a new box even after a vagrant destroy of the existing VM, do the following.

Ensure the box_url variable in the Vagrantfile is set to the correct URL of the new box (config.vm.box_url).

View existing boxes to get the existing box name:

$ vagrant box list

Output:

myBox (virtualbox, 0)

Fully remove the box file:

$ vagrant box remove myBox

Now the box file listed in the Vagrantfile will be downloaded again when running vagrant up.