Class 我怎样才能开玩笑地模仿aws sdk?

Class 我怎样才能开玩笑地模仿aws sdk?,class,jestjs,aws-sdk,Class,Jestjs,Aws Sdk,我试图用玩笑来嘲笑aws sdk。实际上我只关心一个函数。我该怎么做?我读过关于用笑话来模拟类的文档,但是这些文档很复杂,我不太理解 以下是我最好的尝试: handler.test.js 'use strict'; const aws = require('aws-sdk'); const { handler } = require('../../src/rotateSecret/index'); jest.mock('aws-sdk'); const event = { Secret

我试图用玩笑来嘲笑aws sdk。实际上我只关心一个函数。我该怎么做?我读过关于用笑话来模拟类的文档,但是这些文档很复杂,我不太理解

以下是我最好的尝试:

handler.test.js

'use strict';

const aws = require('aws-sdk');
const { handler } = require('../../src/rotateSecret/index');

jest.mock('aws-sdk');

const event = {
  SecretId: 'test',
  ClientRequestToken: 'ccc',
  Step: 'createSecret',
};

describe('rotateSecret', () => {
  it.only('should not get or put a secret', async () => {
    aws.SecretsManager.mockImplementation(() => ({
      getSecretValue: () => ({}),
    }));
    expect.assertions(1);

    await handler(event);

    // You can see what I am trying to do here but it doesn't work
    expect(aws.SecretsManager.getSecretManager).not.toHaveBeenCalled();
  });
});
handler.js

exports.handler = async (event) => {
  const secretsManager = new aws.SecretsManager();
  const secret = await secretsManager.describeSecret({ SecretId: event.SecretId }).promise();

  if (someCondition) {
    console.log("All conditions not met");
    return;
  }

  return secretsManager.getSecretValue(someParams)
};


好的,我的方法如下:

AWS-SDK模拟
aws sdk
创建一个实际的模拟,并将其放入项目根目录下的
\uuuuuuuuuuu mocks\uuuuuuuuu/aws sdk.js
文件中

/\uuuuu mocks\uuuu/aws-sdk.js
AWS级{
静态SecretsManager=class{
descripebsecret=jest.fn(()=>{
返回{promise:()=>promise.resolve({ARN:“custom-arn1”,Name:“descripbesec”})
});
getSecretValue=jest.fn(()=>{
返回{promise:()=>promise.resolve({ARN:“custom-arn2”,Name:“getSecretVal”})
});
};
}
module.exports=AWS;
我在
SecretsManager
之前使用过static,因为
AWS
类从未实例化,但它希望访问
SecretsManager

SecretsManager
中,我定义了两个函数,并使用
jest.fn
对它们进行了存根

现在,与您在测试文件中所做的内容相同:

jest.mock('aws-sdk');
如何测试
要测试您的模拟函数是否被调用,这是一个棘手的部分(因此我将在本文末尾对此进行详细说明)

更好的方法是在所有处理完成后针对主函数的最终结果进行断言

断言
回到您的测试文件中,我只需使用
await
(正如您已经使用过的)调用处理程序,然后针对最终结果进行断言,如下所示:

//test.js
描述(“rotateSecret”,()=>{
it.only(“不应获取或放置机密”,async()=>{
const event={name:“event”};
const result=等待处理程序(事件);
expect(result).toEqual(“无论您的函数期望返回什么”);
});
});
测试Secret Manager的函数调用
为此,您需要调整主
handler.js
文件本身,并需要从主函数体中取出对机密管理器的调用,如下所示:

const secretsManager=new aws.secretsManager();//{
const secret=等待secretsManager
.describeSecret({SecretId:event.SecretId})
.promise();
如果(某些条件){
console.log(“未满足所有条件”);
返回;
}
返回secretsManager.getSecretValue(someParams);
};
然后回到
test.js
文件中,在启动处理程序函数之前,您需要类似地声明
SecretsManager
调用,如下所示:

//test.js
描述(“rotateSecret”,()=>{
const secretsManager=new aws.secretsManager();//{
const event={name:“event”};
等待处理程序(事件);
//现在您可以对函数调用进行断言
expect(secretsManager.descripesecret).tohavebeincall();
//或者检查传递的参数是否正确
期望(secretsManager.descripebsecret).已被调用({
秘密的,秘密的,
});
});
});
这将允许您对函数调用以及传递的参数进行断言

我在函数范围之外声明它的原因是告诉Jest,
secretsManager
应该存在于全局范围的某个地方,并且应该从那里使用它

以前,我们在函数范围内声明了它,因此Jest将调用它,但我们无法访问它

我们不能像这样直接引用它
AWS.SecretsManager.getSecretManager
,因为
getSecretManager
方法只有在实例化
SecretsManager
类之后才可用(即使这样做了,也会得到一个新的类实例,它对任何断言都没有帮助)

__mock__/aws.js伪模块的缺点
明显的问题是——您在每次调用时都要对函数进行存根,可能您不希望这样

也许你只想在一个特定的测试中删除一次,但是对于其他测试,你想让它正常运行

在这种情况下,您不应该创建
\uuuuuumocks\uuuuu
文件夹

相反,创建一个一次性假函数,但要像以前一样确保
SecretsManager
调用在测试文件的外部范围内

//test.js
const aws=要求(“aws sdk”);
描述(“rotateSecret”,()=>{
//在外部范围中声明它
const secretsManager=new aws.secretsManager();
it.only(“不应获取或放置机密”,async()=>{
const event={name:“event”};
//仅为此实例创建模拟
secretsManager.descripebsecret=jest.fn().mockImplementationOnce(()=>Promise.resolve(“假值”);
等待处理程序(事件);
expect(secretsManager.descripesecret).tohavebeincall();
期望(secretsManager.descripebsecret).已被调用({
秘密的,秘密的,
});
});
});

您能否为
处理程序
文件提供代码,我想看看您的函数如何实例化
AWS
类和
secretsManager
client@nishkaush:当然!我已经更新了问题,以包括处理程序的相关部分。