Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest - Mocking a factory function

Function I want to test is createCarAndDrive() which uses Car module. I'd like to mock one function in the Car module so its actual function is not called but the mock function.

So, the Car function returns two functions gas() and brake(). Car is implemented by using factory function pattern. So those two functions are wrapped in Car and won't be exposed until Car is called.

Is it somehow possible to mock the function brake() to return false?

Here's the implementation.

// Car.js
function Car({ name, model }) {
  function gas(speed) {
    return `${name} ${model} goes forward at a speed of ${speed}km/h`;
  }
  function brake() {
    return true;
  }

  return {
    gas,
    brake,
  };
}

// driver.js
function createCarAndDrive() {
  const car = Car({ name: 'Fiat', model: 'Punto' });
  car.gas(123);
  return car.brake();
}

// driver.test.js
describe('drive', () => {
  beforeEach(() => {
    // How to mock function inside a function?
    jest.mock('./Car', () => ({
      brake: jest.fn().mockImplementation(() => false),
    }));
  });

  test('it should not brake', () => {
    const itHitBreak = createCarAndDrive();
    expect(itHitBreak).toBe(false);
  });
});
like image 735
anmatika Avatar asked Oct 25 '25 14:10

anmatika


1 Answers

jest.mock factory functions don't work within test functions.

Move jest.mock to the top level scope of your test and it should work:

import { createCarAndDrive } from './driver';

jest.mock('./Car', () => ({
  Car: () => ({
    gas: () => 'mock gas',
    brake: () => false
  })
}));

describe('drive', () => {
  test('it should not brake', () => {
    const itHitBreak = createCarAndDrive();
    expect(itHitBreak).toBe(false);  // Success!
  });
});
like image 169
Brian Adams Avatar answered Oct 27 '25 03:10

Brian Adams