Search code examples
javascriptunit-testingjasminemockingjasmine-node

How to mock a module that is required in another module with Jasmine


const Client = require('./src/http/client');

module.exports.handler = () => {
    const client = new Client();
    const locationId = client.getLocationId(123);
};

How can I test this module asserting that the client.getLocationId has been called with the 123 argument in Jasmine?

I know how to achieve that with Sinon, but I have no clue about Jasmine.


Solution

  • Where with Sinon you would do:

    Sinon.spy(client, 'getLocationId');
    
    ...
    
    Sinon.assert.calledWith(client.getLocationId, 123);
    

    with Jasmine you do:

    spyOn(client, 'getLocationId');
    
    ...
    
    expect(client.getLocationId).toHaveBeenCalledWith(123);
    

    Update: So, what you need is to mock the Client module when it's required by the module you're testing. I suggest using Proxyquire for this:

    const proxyquire = require('proxyquire');
    const mockedClientInstance = {
      getLocationId: () => {}
    };
    const mockedClientConstructor = function() {
      return mockedClientInstance;
    };
    
    const moduleToTest = proxyquire('moduleToTest.js', {
      './src/http/client': mockedClientConstructor
    });
    

    This will inject your mock as a dependency so that when the module you're testing requires ./src/http/client, it will get your mock instead of the real Client module. After this you just spy on the method in mockedClientInstance as normal:

    spyOn(mockedClientInstance, 'getLocationId');
    moduleToTest.handler();
    expect(mockedClientInstance.getLocationId).toHaveBeenCalledWith(123);