Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Sinon.restore不适用于存根和测试AWS功能_Node.js_Amazon Web Services_Testing_Aws Sdk_Sinon - Fatal编程技术网

Node.js Sinon.restore不适用于存根和测试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

因此,我试图编写一些测试来测试我一直在编写的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('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;
此代码执行以下操作

  • aws的存根
    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…}
    的方法,看看会发生什么。再次感谢!