Class 我怎样才能开玩笑地模仿aws sdk?
我试图用玩笑来嘲笑aws sdk。实际上我只关心一个函数。我该怎么做?我读过关于用笑话来模拟类的文档,但是这些文档很复杂,我不太理解 以下是我最好的尝试: handler.test.jsClass 我怎样才能开玩笑地模仿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
'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:当然!我已经更新了问题,以包括处理程序的相关部分。