Node.js - Mock result of a promise
Solution 1
Okay, i figured it out. The function doPostRequest
was loaded using require
, on the top of the file using const doPostRequest = require('./doPostRequest.js').doPostRequest;
In order to mock the data that comes back from a function that is loaded using require
i had to use a node module called mock-require. There are more modules that can take care of this (proxyquire is a populair one) but i picked mock-require (i did not have a specific reason for choosing mock-require).
For anyone else that is stuck with a similar problem, try mock-require to mock the respose from files that are loaded using require
.
Solution 2
You can use Promise.resolve to return a promise with any given value.
Promise.resolve(“hello world”);
Related videos on Youtube
Mitch
Updated on June 04, 2022Comments
-
Mitch almost 2 years
I want to mock the result of a function within a node module so that i can run assertions. Considering the following node module:
const doPostRequest = require('./doPostRequest.js').doPostRequest; const normalizeSucessResult = require('./normalizer.js').normalizeSucessResult; const normalizeErrorResult = require('./normalizer.js').normalizeErrorResult; exports.doPost = (params, postData) => { return doPostRequest(params, postData).then((res) => { const normalizedSuccessResult = normalizeSucessResult(res); return normalizedSuccessResult; }).catch((err) => { const normalizedErrorResult = normalizeErrorResult(err); return normalizedErrorResult; }) }
The function
doPostRequest
returns a promise. How can i fake the return value of this promise so that i can assert ifnormalizeSucessResult
has been called? So for i have tried:const normalizeSucessResult = require('./normalizer.js'); const doPostRequest = require('./doPostRequests.js'); const doPost = require('./doPost.js'); it('runs a happy flow scenario', async () => { let normalizeSucessResultStub = sinon.stub(normalizeSucessResult, 'normalizeSucessResult'); let postData = { body: 'Lorum ipsum' }; let params = { host: 'someUrl', port: 433, method: 'POST', path: '/' }; sinon.stub(doPostRequest, 'doPostRequest').resolves("some response data"); //Fake response from doPostRequest return doPost.doPost(params, postData).then((res) => { //res should be equal to some response data expect(normalizeSucessResultStub).to.have.been.calledOnce; expect(normalizeSucessResultStub).to.have.been.with("some response data"); }); });
The
doPostRequest
module looks like this:const https = require('https') module.exports.doPostRequest = function (params, postData) { return new Promise((resolve, reject) => { const req = https.request(params, (res) => { let body = [] res.on('data', (chunk) => { body.push(chunk) }) res.on('end', () => { try { body = JSON.parse(Buffer.concat(body).toString()) } catch (e) { reject(e) } resolve(body) }) }) req.on('error', (err) => { reject(err) }) if (postData) { req.write(JSON.stringify(postData)) } req.end() }) }
-
Estus Flask over 5 yearsWhere's doPostRequest defined? Please, post all relevant code.
-
Mitch over 5 yearsThe
doPostRequest
module is defined in a separate file. I have updated the code in order to show where it lives. If you have any ideas on how to solve this, please share. Im getting more confused by the minute... -
Estus Flask over 5 yearsI'm not up to detailed answer, but you need to mock the module where doPostRequest was exported from (with Proxyquire or something similar) and do this before you import the module where it's used the first time (i.e doPost) module. You cannot do this with Sinon. You can only mock existing methods with Sinon, while doPostRequest is used as a function, not a method. Btw, Jest handles module mocking natively, you could do this easier by switching to it.
-
-
Mitch over 5 yearsThanks for your help, i tried that in my code with
sinon.stub(doPostRequest, 'doPostRequest').resolves("some response data");
. Than when i call the method,res
should be equal tosome response data
, but it is not. Can you show me how i can use it within my test so thatres
would be equal tosome response data
?