问题
I am trying to stub
a module.exports
function. But I have some trouble. I will give you a sudo code of the situation.
MyController.js
const sendOTPOnPhone = rewire('../../src/services/OtpService/sendOTPOnPhone')
module.exports = async function(req, res) {
const { error, data } = await sendOTPOnPhone(req.query.phone) //this is I want to stub
if(error)
return return res.send(error)
return res.send(data)
}
sendOTPService.js
module.exports = async function(phone) {
const result = await fetch(`external-api-call`)
if(result.status !== 'success')
return {
error: "Failed to send OTP!",
data: null
}
return {
error: null,
data: result
}
}
sendOTPTest.js
const expect = require('chai').expect
const request = require('supertest')
const sinon = require('sinon')
const rewire = require('rewire')
const sendOTPOnPhone = rewire('../../src/services/OtpService/sendOTPOnPhone')
const app = require('../../src/app')
describe('GET /api/v1/auth/otp/generate', function () {
it('should generate OTP', async () => {
let stub = sinon.stub().returns({
error: null,
data: "OTP sent"
})
sendOTPOnPhone.__set__('sendOTPOnPhone', stub)
const result = await request(app)
.get('/api/v1/auth/otp/generate?phone=8576863491')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200)
expect(stub.calledOnce).to.be.true
console.log(result.body)
// expect(result).to.equal('promise resolved');
})
})
Above test is failing, stub is not being called. I don't know what am I missing? If I do this in my sendOTPService:
const sendOTP = async function() {}
module.exports = {
sendOTP
}
and this in the controller.
const { error, data } = sendOTPOnPhone.sendOTPOnPhone(req.query.phone)
It works.
But I import it like const {sendOTPOnPhone } = require('../sendOTPService')
It doesn't work.
I am aware that destructing changes the reference of the object.
Can someone suggest a workaround?
Is it possible to achieve this using rewire
? OR It can be done with proxyquire
.
Please can someone suggest?
回答1:
Here is the integration testing solution using proxyquire, you should use Globally override require.
app.js
:
const express = require('express');
const controller = require('./controller');
const app = express();
app.get('/api/v1/auth/otp/generate', controller);
module.exports = app;
controller.js
:
let sendOTPOnPhone = require('./sendOTPOnPhone');
module.exports = async function(req, res) {
const { error, data } = await sendOTPOnPhone(req.query.phone);
if (error) return res.send(error);
return res.send(data);
};
sendOTPOnPhone.js
:
module.exports = async function(phone) {
const result = await fetch(`external-api-call`);
if (result.status !== 'success')
return {
error: 'Failed to send OTP!',
data: null,
};
return {
error: null,
data: result,
};
};
sendOTP.test.js
:
const request = require('supertest');
const sinon = require('sinon');
const proxyquire = require('proxyquire');
describe('GET /api/v1/auth/otp/generate', function() {
it('should generate OTP', async () => {
let stub = sinon.stub().resolves({
error: null,
data: { message: 'OTP sent' },
});
stub['@global'] = true;
const app = proxyquire('./app', {
'./sendOTPOnPhone': stub,
});
const result = await request(app)
.get('/api/v1/auth/otp/generate?phone=8576863491')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200);
sinon.assert.calledOnce(stub);
console.log(result.body);
});
});
Integration test results with coverage report:
GET /api/v1/auth/otp/generate
{ message: 'OTP sent' }
✓ should generate OTP (2373ms)
1 passing (2s)
-------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------|---------|----------|---------|---------|-------------------
All files | 68.75 | 25 | 50 | 73.33 |
app.js | 100 | 100 | 100 | 100 |
controller.js | 83.33 | 50 | 100 | 100 | 5
sendOTPOnPhone.js | 20 | 0 | 0 | 20 | 2-4,8
-------------------|---------|----------|---------|---------|-------------------
source code: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/60599945
来源:https://stackoverflow.com/questions/60599945/stub-a-standalone-module-exports-function-using-rewire