Node.js Sinon.restore不适用于存根和测试AWS功能
因此,我试图编写一些测试来测试我一直在编写的AWS包装器库。 这些测试单独运行,没有任何问题,但不会全部作为一个“描述”块运行Node.js Sinon.restore不适用于存根和测试AWS功能,node.js,amazon-web-services,testing,aws-sdk,sinon,Node.js,Amazon Web Services,Testing,Aws Sdk,Sinon,因此,我试图编写一些测试来测试我一直在编写的AWS包装器库。 这些测试单独运行,没有任何问题,但不会全部作为一个“描述”块运行 const AWS_REGION = 'eu-west-2'; const aws = require('aws-sdk'); const chai = require('chai'); const expect = chai.expect; const sinon = require('sinon'); const sinonChai = require('sino
const AWS_REGION = 'eu-west-2';
const aws = require('aws-sdk');
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
chai.use(sinonChai);
// These help:
// https://stackoverflow.com/questions/26243647/sinon-stub-in-node-with-aws-sdk
// https://stackoverflow.com/questions/61516053/sinon-stub-for-lambda-using-promises
describe('SQS Utilities Test', () => {
afterEach(() => {
sinon.restore();
});
it('should add to SQS', async () => {
sinon.stub(aws.config, 'update');
const sqs = {
sendMessage: sinon.stub().returnsThis(),
promise: sinon.stub()
};
sinon.stub(aws, 'SQS').callsFake(() => sqs);
// these use the above stubbed version of aws
const AWSUtilities = require('../index').AWSUtilities;
const awsUtilities = new AWSUtilities(AWS_REGION);
const response = await awsUtilities.postToSQS('https://example.com', { id: 1}, 'chicken');
expect(sqs.sendMessage).to.have.been.calledOnce;
});
it('should get from SQS', async () => {
sinon.stub(aws.config, 'update');
const sqs = {
receiveMessage: sinon.stub().returnsThis(),
promise: sinon.stub()
};
sinon.stub(aws, 'SQS').callsFake(() => sqs);
// these use the above stubbed version of aws
const AWSUtilities = require('../index').AWSUtilities;
const awsUtilities = new AWSUtilities(AWS_REGION);
const response = await awsUtilities.getFromSQS('https://example.com');
expect(sqs.receiveMessage).to.have.been.calledOnce;
});
...
我注意到,在第二个测试中,我得到的错误是sqs。receiveMessage不是一个函数
,这意味着第二个测试使用的是第一个测试中的sqs
对象(如果我将receiveMessage
添加到第一个测试sqs
对象中,我可以进一步验证错误的变化)
这是sinon restore中的一个bug,还是我写的东西不正确?这是整个库:这不是Sinon的问题。这是一个关于如何存根AWS SDK的问题。让我们分析一下您共享的代码中发生的事情
const sqs={
sendMessage:sinon.stub().returnsThis(),
承诺:sinon.stub()
};
sinon.stub(aws,'SQS').callsFake(()=>SQS);
//它们使用上述aws的存根版本
const AWSUtilities=require(“../index”).AWSUtilities;
此代码执行以下操作
SQS
AWSUtilities.js
(基于github中的源代码)AWSUtilities.js
在加载后立即执行以下操作
const aws=require('aws-sdk');
const sqs=新的aws.sqs();
//删除代码以演示该概念
上面的代码创建了一个内部sqs
对象,在本例中,该对象是使用stubbed aws模块创建的。在节点中,使用require
加载模块后,该模块将缓存在内存中,即上述代码仅执行一次
因此,当第一个it()
依次执行它时,第一次加载AWSUtilities.js
,并将其缓存。任何后续调用都将获取缓存版本。调用sinon.restore
时,它只恢复aws
模块的SQS
功能,而不恢复在AWSUtilities.js
中创建的SQS
对象
我希望这能解释你看到这种行为的原因
有多种方法可以解决此问题。依赖注入,使用诸如proxyquire、rewire、在所有测试用例之前从中心位置截取aws等模块
下面是一个选项,可以在这里显示的测试用例中修复它
description('SQS实用程序测试',()=>{
让我们一起来吧,sqsStub;
之前(()=>{
sinon.stub(aws.config,'update');
sqsStub={
sendMessage:sinon.stub().returnsThis(),
receiveMessage:sinon.stub().returnsThis(),
承诺:sinon.stub()
};
sinon.stub(aws,'SQS').callsFake(()=>SQS);
AWSUtilities=require(“../index”).AWSUtilities;
});
之后(()=>{
sinon.restore();
});
它('应该添加到SQS',异步()=>{
常数awsUtilities=新awsUtilities(AWS_地区);
const response=wait awsUtilities.postToSQS('https://example.com“,{id:1},'鸡'”;
expect(sqsStub.sendMessage).to.have.been.calledOnce;
});
它('应该从SQS获取',异步()=>{
常数awsUtilities=新awsUtilities(AWS_地区);
const response=await awsUtilities.getFromSQS('https://example.com');
expect(sqsStub.receiveMessage).to.have.been.calledOnce;
});
});
是否必须在此处定义此行:(常量sqs)?这就是sinon无法恢复的原因。您可以使用rewire for require在其内部的每个require功能中;如果您不想更改AWSUtilities实现。这似乎是因为您在测试文件中存根了不同的aws包,而在索引文件中存根了不同的aws包。你能在这里发布你的索引/AWSUtilities文件吗?你能发布测试中的代码吗?嗨,谢谢你非常透彻的回答,我真的很感激,我不知道它是如何工作的。我想将sqsStub本身添加到it('should'
函数中的原因是,我可以为returns创建独特的行为(例如不同的返回值)。对于每个存根函数(例如sendMessage
),此
语句。看来我必须找到更好的方法,我将尝试类似于sqsStub={…sqsStub,sendMessage:…returns…}
的方法,看看会发生什么。再次感谢!