0

I have a handy set of apiHelpers. One of the functions is a wrapper around axios's get method called getWrapper

const getWrapper = url => (endpoint, headers = {}) => {
  return axios.get(`${url}${endpoint}`, { headers: { ...getHeaders(), ...headers } });
};

For unauthenticated calls, I have a getUnauthenticatedApiHelper function that calls getWrapper. getWrapper does a few things, one of which is concatenating the supplied endpoint to BASE_URL which is an env variable.

export const getUnauthenticatedApiHelper = (endpoint, headers) => getWrapper(BASE_URL)(endpoint, headers);

My test calls getUnauthenticatedApiHelper and expects that it then calls getWrapper.

describe('apihelpers', () => {
  test('getUnauth', () => {
    const getWrapper = jest.fn();
    var wtf = getUnauthenticatedHelper('end/point/');
    console.log(wtf);
    expect(getWrapper).toHaveBeenCalled();
  });
});

When I log out the result, I can see that the endpoint has correctly been concatenated with BASE_URL, however, my test fails with the error Expected mock function to have been called, but it was not called.

Whether or not this is a valid thing to be testing or not is beside the point atm because I'm just trying to get my head around how to effectively use jest. I have been experimenting with this in an online repl - and no matter what I do, I keep running into the problem of getWrapper not being called which makes me believe that there’s something fundamental I'm misunderstanding about jest.fn() - so what am I missing and how should I be testing that getWrapper is called?

Here is an online repl of what I've been experimenting with

Lin Du
  • 88,126
  • 95
  • 281
  • 483
rakitin
  • 1,943
  • 6
  • 25
  • 51
  • 1
    It's unclear from the question how modules are organized. `getWrapper` stub won't be called by magic. A module that contains original `getWrapper` needs to be mocked. – Estus Flask Feb 21 '19 at 16:55
  • @estus getWrapper is a function defined in the same module as getUnauthenticatedHelper. my thinking is that by executing the getUnauthenticatedHelper function in my test, jest will look for a function definition called getWrapper and then invoke it. In this case, jest.fn() is providing the function definition (skipping over the implementation of course) and toHaveBeenCalled should be true. Is my understanding incorrect? I've tried to extract away the complications of module organization by defining these functions in the test - see: https://repl.it/repls/CyberRustyVirus – rakitin Feb 21 '19 at 17:06
  • 1
    You can't mock a function that is used in the same module. See the links, https://stackoverflow.com/questions/52235196/how-to-mock-import-es6-export-methods-with-jest-and-babel-jest . *jest will look for a function definition called getWrapper and then invoke it* - it won't, this isn't specific to Jest, JS just doesn't work like that. In this case you need to mock `axios.get`, not a function that uses it. – Estus Flask Feb 21 '19 at 17:14

1 Answers1

0

I made your demo works, you can check here: https://repl.it/repls/IllStandardDesigner

getWrapper.js:

function getWrapper(url) {
  return (endpoint, headers={}) => (
    `${url}${endpoint}`
  );
}

module.exports = getWrapper

getUnauthenticatedHelper.js:

const getWrapper = require('./getWrapper');

const BASE_URL = 'foo/';

const getUnauthenticatedHelper = (endpoint, headers) => getWrapper(BASE_URL)(endpoint, headers);
module.exports = getUnauthenticatedHelper

Unit test:

const add = require('./add');
const getWrapper = require('./getWrapper');
const getUnauthenticatedHelper = require('./getUnauthenticatedHelper');

describe('add', () => {
  it('should add two numbers', () => {
    expect(add(1, 2)).toBe(3);
  });
});

jest.mock('./getWrapper', () => {
  return jest.fn((url) => {
    return (endpoint, headers = {}) => (
      `${url}${endpoint}`
    );
  })
})

describe('apihelpers', () => {
  test('getUnauth', () => {
    var wtf = getUnauthenticatedHelper('end/point/');
    console.log(wtf);
    expect(getWrapper).toHaveBeenCalled();
  });
});

Unit test result:

Jest v24.9.0 node v10.16.3 linux/amd64
 jest --colors --config /home/runner/config.json
 PASS  ./add-test.js
  add
    ✓ should add two numbers (5ms)
  apihelpers
    ✓ getUnauth (57ms)

  console.log add-test.js:22
    foo/end/point/

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        2.788s
Ran all test suites.
Lin Du
  • 88,126
  • 95
  • 281
  • 483