David Faizulaev
David Faizulaev

Reputation: 5751

How to mock required module function with Jest?

I have the following code which I need to test:

createCassandraDriver

const driver = require('cassandra-driver')
module.exports = ({
  cassandra_user,
  cassandra_password,
  cassandra_address
}) => {
  return new Promise((resolve, reject) => {
    try {
      const client = new driver.Client({
        contactPoints: cassandra_address.split(','),
        authProvider: authProvider(cassandra_user, cassandra_password),
        queryconfig: {
          consistency: driver.types.consistencies.quorum
        }
      })
      return resolve(client)
    } catch (e) {
      reject(e)
    }
  })
}

I'm trying to mock the call to 'driver.Client'. I tried doing it using 'spyOn', like so:

'use strict';
const rewire = require('rewire'),
      driver = require('cassandra-driver'),
      createCassandraDriver = require('../../lib/createCassandraDriver.js');

const defaultArguments = () => {
  return {
    'cassandra_address': '127.0.0.1',
    'cassandra_user': 'cassandra_user',
    'cassandra_password': 'cassandra_password'
  };
}

jest.mock("cassandra-driver");

describe('Create cassandra driver tests', function () {
  describe('success flow', function () {
    it('Should pass without any errors ', async function () {    
        await createCassandraDriver(defaultArguments())
    });
  });
  afterEach(function () {
    jest.restoreAllMocks()
  });
});

mocks file

const driver = jest.genMockFromModule('cassandra-driver');
driver.Client = function () {return "cassandra_client"}    
module.exports = driver;

But I get an error message that says 'driver is not a function' which is true.

How I can mock the call to 'driver.Client' then?

Upvotes: 2

Views: 6887

Answers (2)

mpontus
mpontus

Reputation: 2203

I suggest using Manual Mocks to mock external dependencies in your Jest tests.


  1. Create a directory called __mocks__ next to node_modules.

  2. Create file __mocks__/cassandra-driver.js:

module.exports = {
  types: {
    consistencies: {
      quorum: null
    }
  },
  Client: jest.fn()
};
  1. Add following line to your test file:
jest.mock("cassandra-driver");

Now every time you import cassandra-driver in your test, or in any files imported in your test, the module which you implemented in step 2 will be imported instead.

This allows you to call driver.Client with any of the mock methods to replace implementation, stub return value, or access mock instances.

Here's a complete test example:

import driver from "cassandra-driver";
import createCassandraDriver from "./createCassandraDriver";

jest.mock("cassandra-driver");

const clientStub = {
  foo: "bar"
};

driver.Client.mockImplementation(() => clientStub);

it("renders without crashing", async () => {
  const result = await createCassandraDriver({
    cassandra_user: "foo",
    cassandra_password: "bar",
    cassandra_address: "baz"
  });

  expect(result).toEqual(clientStub);
});

Upvotes: 3

Billy Reilly
Billy Reilly

Reputation: 1542

You can only use jest.spyOn to spy on the method of an object - here, driver is a private variable within the createCassandraDriver module so we can't use that.

Looks like you're using the rewire package from your use of __set__? If so, I think you should be able to achieve what you want by using jest.fn:

let createCassandraDriverSpy = jest.fn(clientMock);
createCassandraDriver.__set__('driver', createCassandraDriverSpy)

Upvotes: 1

Related Questions