Reputation: 1801
I have searched quite a bit, and whilst there are many questions asked about mocking functions, none of the solutions I've found work for my setup, and I'm not quite sure why. I have the following:
questionnaire-service.js
const service = require('./request-service')();
function questionnaireService() {
function createQuestionnaire() {
const opts = {
url: `http://some-url.com`,
body: {
data: "some-data"
}
};
return service.post(opts);
}
return Object.freeze({
createQuestionnaire
});
}
module.exports = questionnaireService;
request-service.js
const got = require('got');
const merge = require('lodash.merge');
function requestService() {
function post(options) {
let opts = {
method: 'POST',
headers: {
accept: 'application/json',
'Content-Type': 'application/json'
},
json: true,
body: options.body
};
opts = merge(opts, options);
return got(opts.url, opts);
}
return Object.freeze({
post
});
}
module.exports = requestService;
I am trying to write tests for the questionnaire service, and want to mock the 'post' function. I have tried the following
questionnaire-service.test.js
const requestService = require('./request-service')();
const questionnaireService = require('./questionnaire-service')();
const createdQuestionnaire = require('./test-fixtures/res/get_questionnaire.json');
describe('questionnaire service routes', () => {
it('Should create a new questionnaire', async () => {
const spy = jest.spyOn(requestService.post);
spy.mockReturnValue(createdQuestionnaire);
const response = await questionnaireService.createQuestionnaire();
expect(requestService.post).toBeCalled();
expect(response).toMatch(createdQuestionnaire);
}
it('Should create a new questionnaire', async () => {
jest.doMock('./questionnaire-service', () =>
jest.fn(() => ({
createQuestionnaire: () => createdQuestionnaire
}))
);
const response = await questionnaireService.createQuestionnaire();
expect(questionnaireService.createQuestionnaire).toBeCalled();
expect(response).toMatch(createdQuestionnaire);
}
it('Should create a new questionnaire', async () => {
jest.doMock('./request-service', () =>
jest.fn(() => ({
post: () => createdQuestionnaire
}))
);
const response = await questionnaireService.createQuestionnaire();
expect(requestService.post).toBeCalled();
expect(response).toMatch(createdQuestionnaire);
}
});
All of the above yield the same error: RequestError: getaddrinfo ENOTFOUND some_token some_token:443
which sounds like it's being thrown by the 'GOT' module not finding a url to hit. Can someone shed some light on how to get this to work correctly?
Upvotes: 0
Views: 933
Reputation: 3873
When you make a require("somemodule")
it loads this module and executes it, so it executes require
calls inside this module. Then all the modules are cached, so whenever you make a require
again, it doesn't execute again, and returns already cached dependencies.
When you do doMock
, you need to reset this cache, and make new require
in your test for everything, that depends on mocked module.
jest.doMock('./questionnaire-service', () =>
jest.fn(() => ({
createQuestionnaire: () => createdQuestionnaire
}))
);
jest.resetModules();
const questionnaireService = require(`questionnaire-service`)();
const response = await questionnaireService.createQuestionnaire();
Upvotes: 1