我正在尝试stub
的{{1}}功能。但是我有些麻烦。我会给你一个情况的sudo代码。
MyController.js
module.exports
sendOTPService.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)
}
sendOTPTest.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
}
}
以上测试失败,未调用存根。我不知道我在想什么?如果我在sendOTPService中这样做:
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');
})
})
,并且在控制器中。
const sendOTP = async function() {}
module.exports = {
sendOTP
}
有效。
但是我像const { error, data } = sendOTPOnPhone.sendOTPOnPhone(req.query.phone)
一样导入它。它不起作用。
我知道破坏会更改对象的引用。
有人可以建议解决方法吗?
是否可以使用const {sendOTPOnPhone } = require('../sendOTPService')
来实现?或者可以通过rewire
完成。
请有人建议吗?
答案 0 :(得分:1)
这是使用proxyquire的集成测试解决方案,您应该使用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);
});
});
具有覆盖率报告的集成测试结果:
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
-------------------|---------|----------|---------|---------|-------------------
源代码:https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/60599945