gpt4 book ai didi

class - 我怎样才能 Jest 模拟 aws-sdk?

转载 作者:行者123 更新时间:2023-12-05 09:37:00 25 4
gpt4 key购买 nike

我正在尝试 Jest 模拟 aws-sdk。其实我只关心一个功能。我怎样才能做到这一点?我已经阅读了关于用 Jest 模拟类的文档,但是文档很复杂,我不太明白。

这是我最好的尝试:

处理程序.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();
});
});

处理程序.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 创建一个实际的 mock,并将其放入项目根目录下的 __mocks__/aws-sdk.js 文件中

// __mocks__/aws-sdk.js

class AWS {
static SecretsManager = class {
describeSecret = jest.fn(() =>{
return { promise: ()=> Promise.resolve({ ARN: "custom-arn1", Name: "describeSec" })}
});
getSecretValue = jest.fn(() =>{
return {promise: ()=> Promise.resolve({ ARN: "custom-arn2", Name: "getSecretVal" })
});
};
}

module.exports = AWS;

我在 SecretsManager 之前使用了 static,因为 AWS 类从未实例化,但它想要访问 SecretsManager 类。

SecretsManager 中,我定义了 2 个函数并使用 jest.fn 将它们 stub 。

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

jest.mock('aws-sdk');

如何测试


To test if your mock functions are called, thats the tricky part (so i will detail that at the end of this post).

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

断言


回到您的测试文件中,我将简单地使用 await 调用处理程序(正如您已经拥有的那样),然后像这样对最终结果进行断言:

// test.js

describe("rotateSecret", () => {
it.only("should not get or put a secret", async () => {
const event = {name:"event"};
const result = await handler(event);
expect(result).toEqual("whatever-your-function-is-expected-to-return");
});
});

测试 Secret Manager 的函数调用


为此,您需要调整主 handler.js 文件本身,并且需要从主函数体中取出 invocation of secrets Manager,如下所示:

const secretsManager = new aws.SecretsManager(); // <---- Declare it in outer scope

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

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

return secretsManager.getSecretValue(someParams);
};

然后回到您的 test.js 文件,您将需要类似地声明 SecretsManager 调用,然后再启动您的处理程序函数,如下所示:

//test.js

describe("rotateSecret", () => {
const secretsManager = new aws.SecretsManager(); // <---- Declare it in outer scope

it.only("should not get or put a secret", async () => {
const event = {name:"event"};

await handler(event);

// Now you can make assertions on function invocations
expect(secretsManager.describeSecret).toHaveBeenCalled();

// OR check if passed args were correct
expect(secretsManager.describeSecret).toHaveBeenCalledWith({
SecretId: event.SecretId,
});
});
});

这将允许您对函数调用以及传递的参数进行断言。

The reason I declare it outside function scope is to tell Jest that secretsManager should be existing somewhere in global scope and it should be used from there.

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

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

__mocks__/aws.js 假模块的缺点


明显的问题是 - 您在每次调用时都对函数进行 stub 处理,也许您不希望这样。

也许您只想针对特定测试将其 stub 一次,但对于其余测试,您希望它正常运行。

在这种情况下,您不应创建 __mocks__ 文件夹。

相反,创建一个一次性伪造但确保您的 SecretsManager 调用像以前一样在测试文件的外部范围内。

//test.js
const aws = require("aws-sdk");

describe("rotateSecret", () => {
// Declare it in outer scope
const secretsManager = new aws.SecretsManager();

it.only("should not get or put a secret", async () => {
const event = {name:"event"};

// Create a mock for this instance ONLY
secretsManager.describeSecret = jest.fn().mockImplementationOnce(()=>Promise.resolve("fake-values"));

await handler(event);
expect(secretsManager.describeSecret).toHaveBeenCalled();
expect(secretsManager.describeSecret).toHaveBeenCalledWith({
SecretId: event.SecretId,
});
});
});

关于class - 我怎样才能 Jest 模拟 aws-sdk?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64604776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com