Search code examples
typescriptaxiosmockingsinon

How to mock a standalone imported function with sinon


How can I mock this axios import with sinon and then use expectations ? I have tried:

 import axios from 'axios';
 axiosMock = sinon.mock(axios);

but the expectation fails :

describe('Random test', () => { 
 it('should run the test', async () => { 
    axiosMock.withArgs(sinon.match.any).once(); 
    await getName();
 } 
}

The function under test is :

import axios, { AxiosRequestConfig } from 'axios';

async function getName() {
  const config: AxiosRequestConfig = {
    method: 'GET',
    url: ' someUrl',
    headers: {},
  };
  const res = await axios(config);
  return res;
}

Solution

  • Sinon doesn't support stub standalone function imported from a module. A solution is to use link-seams. Therefore, we need to use proxyquire to construct the seams.

    E.g.

    getName.ts:

    import axios, { AxiosRequestConfig } from 'axios';
    
    export async function getName() {
      const config: AxiosRequestConfig = {
        method: 'GET',
        url: 'someUrl',
        headers: {},
      };
      const res = await axios(config);
      return res;
    }
    

    getName.test.ts:

    import proxyquire from 'proxyquire';
    import sinon from 'sinon';
    
    describe('68212908', () => {
      it('should pass', async () => {
        const axiosStub = sinon.stub().resolves('mocked response');
        const { getName } = proxyquire('./getName', {
          axios: axiosStub,
        });
        const actual = await getName();
        sinon.assert.match(actual, 'mocked response');
        sinon.assert.calledWithExactly(axiosStub, {
          method: 'GET',
          url: 'someUrl',
          headers: {},
        });
      });
    });
    

    test result:

      68212908
        ✓ should pass (1399ms)
    
    
      1 passing (1s)
    
    ------------|---------|----------|---------|---------|-------------------
    File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ------------|---------|----------|---------|---------|-------------------
    All files   |     100 |      100 |     100 |     100 |                   
     getName.ts |     100 |      100 |     100 |     100 |                   
    ------------|---------|----------|---------|---------|-------------------