为什么 sinon 不替换实际的函数调用?
Why isn't sinon replacing the actual function call?
我的函数是:
const PhoneNumber = require('awesome-phonenumber');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const { twiml } = require('twilio');
exports.incoming = (requestBody) => {
const MessagingResponse = twiml.MessagingResponse;
const VoiceResponse = twiml.VoiceResponse;
const pn = new PhoneNumber(requestBody.Body, 'US');
return global.db.Conference.create({})
.then((dbCreate) => {
conferenceId = dbCreate.id;
// Call originator
return twilio.calls.create({
to: requestBody.From,
from: requestBody.To,
url: `${process.env.API_URL}/calls/conference?id=${conferenceId}`
});
})
我的测试是:
const _ = require('lodash');
const sinon = require('sinon');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const { twiml } = require('twilio');
const SmsController = require('../../../controllers/sms');
const twilioIncomingSmsReq = require('../../mocks/twilioIncomingSmsReq');
describe.only('Sms Controller', () => {
let messagingResponseMessageStub;
let conferenceCreateStub;
beforeEach(() => {
messagingResponseMessageStub = sinon.stub(twiml.MessagingResponse.prototype, 'message').returns(true);
conferenceCreateStub = sinon.stub(global.db.Conference, 'create').resolves({ id: 1 });
return;
});
afterEach(() => {
messagingResponseMessageStub.restore();
conferenceCreateStub.restore();
return;
});
it.only('should call the originator and recipient', () => {
let requestBody = _.clone(twilioIncomingSmsReq);
console.log(twilio.calls);
let twilioDialStub = sinon.stub(twilio.calls, 'create').resolves(true);
console.log(twilio.calls);
return SmsController.incoming(requestBody)
.then(() => {
sinon.assert.calledWith(twilioDialStub, {
to: requestBody.From,
from: requestBody.To,
url: `${process.env.API_URL}/calls?id=1`
});
sinon.assert.calledWith(twilioDialStub, {
to: '+number',
from: requestBody.From,
url: `${process.env.API_URL}/calls?id=1`
});
twilioDialStub.restore();
return;
});
});
});
但在我的代码中,调用了实际的 twilion.calls.create
函数。不是存根。我做错了什么?
twilio
引用这些模块中的不同对象。 require('twilio')
是工厂函数。即使使用相同的参数 require('twilio')(...) !== require('twilio')(...)
.
调用它,也应该创建一个新对象
考虑导出 twilio
实例,至少用于测试目的:
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID,
...
exports.twilio = twilio;
我的函数是:
const PhoneNumber = require('awesome-phonenumber');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const { twiml } = require('twilio');
exports.incoming = (requestBody) => {
const MessagingResponse = twiml.MessagingResponse;
const VoiceResponse = twiml.VoiceResponse;
const pn = new PhoneNumber(requestBody.Body, 'US');
return global.db.Conference.create({})
.then((dbCreate) => {
conferenceId = dbCreate.id;
// Call originator
return twilio.calls.create({
to: requestBody.From,
from: requestBody.To,
url: `${process.env.API_URL}/calls/conference?id=${conferenceId}`
});
})
我的测试是:
const _ = require('lodash');
const sinon = require('sinon');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
const { twiml } = require('twilio');
const SmsController = require('../../../controllers/sms');
const twilioIncomingSmsReq = require('../../mocks/twilioIncomingSmsReq');
describe.only('Sms Controller', () => {
let messagingResponseMessageStub;
let conferenceCreateStub;
beforeEach(() => {
messagingResponseMessageStub = sinon.stub(twiml.MessagingResponse.prototype, 'message').returns(true);
conferenceCreateStub = sinon.stub(global.db.Conference, 'create').resolves({ id: 1 });
return;
});
afterEach(() => {
messagingResponseMessageStub.restore();
conferenceCreateStub.restore();
return;
});
it.only('should call the originator and recipient', () => {
let requestBody = _.clone(twilioIncomingSmsReq);
console.log(twilio.calls);
let twilioDialStub = sinon.stub(twilio.calls, 'create').resolves(true);
console.log(twilio.calls);
return SmsController.incoming(requestBody)
.then(() => {
sinon.assert.calledWith(twilioDialStub, {
to: requestBody.From,
from: requestBody.To,
url: `${process.env.API_URL}/calls?id=1`
});
sinon.assert.calledWith(twilioDialStub, {
to: '+number',
from: requestBody.From,
url: `${process.env.API_URL}/calls?id=1`
});
twilioDialStub.restore();
return;
});
});
});
但在我的代码中,调用了实际的 twilion.calls.create
函数。不是存根。我做错了什么?
twilio
引用这些模块中的不同对象。 require('twilio')
是工厂函数。即使使用相同的参数 require('twilio')(...) !== require('twilio')(...)
.
考虑导出 twilio
实例,至少用于测试目的:
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID,
...
exports.twilio = twilio;