为什么我不能用 sinon 正确地存根 twilio 库?
Why can't I properly stub the twilio library with sinon?
在我的代码中,我有:
function handleMessage() {
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
let recordings = twilio.recordings(foundConference.RecordingSid);
console.log('recordings', recordings);
return recordings.remove();
}
在我的存根中,我有:
const sinon = require('sinon');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
exports.twilioRecordings = () => {
console.log('about to stub', twilio.recordings);
sinon.stub(twilio, 'recordings').returns('here');
console.log('finished stub', twilio.recordings);
return;
};
但是,它实际上并没有创建存根函数。它仍然使用原来的 recordings
功能。我做错了什么?
Twilio npm package returns a function which creates a new object on every call, it's not a singleton。因此,您存根的 twilio 实例仅限于测试。
还有 twilio.recordings
(尽管所有其他属性)is defined through the getter function in prototype, so they are read only:
Object.defineProperty(Twilio.prototype,
'recordings', {
get: function() {
return this.api.account.recordings;
}
});
因此,存根实际的 twilio 实例没有任何效果。除非你 change the instance's prototype,但我认为仅仅进行单元测试不值得。
我建议您重构代码以将 twilio 初始化放入单独的方法中:
function getTwilio() {
return require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
}
接下来您的 hangleMessage
将如下所示:
function handleMessage() {
const twilio = this.getTwilio();
const recordings = twilio.recordings(...);
...
}
接下来,在你的测试中你可以存根 getTwilio()
到 return 存根:
const twilioStub = {
recordings: sinon.stub(),
remove: sinon.stub()
}
sinon.stub(myAwesomeModule, 'getTwilio').returns(twilioStub);
你也可以考虑使用mock-require包:
const sinon = require('sinon');
const mock = require('mock-require');
mock('twilio', () => ({
recordings: sinon.stub(),
}));
这里 is a question about how-to mock dependencies,可能还有其他有用的库来存根所需的模块。
希望对您有所帮助。
在我的代码中,我有:
function handleMessage() {
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
let recordings = twilio.recordings(foundConference.RecordingSid);
console.log('recordings', recordings);
return recordings.remove();
}
在我的存根中,我有:
const sinon = require('sinon');
const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
exports.twilioRecordings = () => {
console.log('about to stub', twilio.recordings);
sinon.stub(twilio, 'recordings').returns('here');
console.log('finished stub', twilio.recordings);
return;
};
但是,它实际上并没有创建存根函数。它仍然使用原来的 recordings
功能。我做错了什么?
Twilio npm package returns a function which creates a new object on every call, it's not a singleton。因此,您存根的 twilio 实例仅限于测试。
还有 twilio.recordings
(尽管所有其他属性)is defined through the getter function in prototype, so they are read only:
Object.defineProperty(Twilio.prototype,
'recordings', {
get: function() {
return this.api.account.recordings;
}
});
因此,存根实际的 twilio 实例没有任何效果。除非你 change the instance's prototype,但我认为仅仅进行单元测试不值得。
我建议您重构代码以将 twilio 初始化放入单独的方法中:
function getTwilio() {
return require('twilio')(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
}
接下来您的 hangleMessage
将如下所示:
function handleMessage() {
const twilio = this.getTwilio();
const recordings = twilio.recordings(...);
...
}
接下来,在你的测试中你可以存根 getTwilio()
到 return 存根:
const twilioStub = {
recordings: sinon.stub(),
remove: sinon.stub()
}
sinon.stub(myAwesomeModule, 'getTwilio').returns(twilioStub);
你也可以考虑使用mock-require包:
const sinon = require('sinon');
const mock = require('mock-require');
mock('twilio', () => ({
recordings: sinon.stub(),
}));
这里 is a question about how-to mock dependencies,可能还有其他有用的库来存根所需的模块。
希望对您有所帮助。