用 Jest 和 Typescript 嘲笑 DynamoDB.DocumentClient 的构造函数



在我的TypeScript应用程序中,我在AWS SDK DynamoDB的DocumentClient函数上有包装函数,我想为这些包装函数编写一些单元测试。包装器功能实现如下:

dynamodb.ts

import DynamoDB from 'aws-sdk/clients/dynamodb'
import AWS from 'aws-sdk/global';

const config: DynamoDB.Types.ClientConfiguration = {
httpOptions: {
connectTimeout: 500,
timeout: 1000,
}
}
const service = new DynamoDB(config);
const ddb = new DynamoDB.DocumentClient({ service });
export const putItem = wrap(ddb.put.bind(ddb));
const wrap =
<I, O>(fnc: (args: I) => AWS.Request<O, AWS.AWSError>) => (args: I) => {
return fnc(args).promise()
.then(result => {
log(result);
return result;
});
};

我更喜欢不在DDB表中执行任何实际的端到端的put/get,而只是模拟AWS SDK函数。然而,我在嘲笑DynamoDBDynamoDB.DocumentClient的构造函数时遇到了一些问题。

目前我的单元测试文件如下:

dynamodb.test.ts
import * as sut from "../dynamodb"
import DynamoDB from "aws-sdk/clients/dynamodb";

jest.mock("aws-sdk/clients/dynamodb", () => {
return jest.fn().mockImplementation(() => {
const documentClient = jest.fn().mockImplementation(() => {
const awsSdkPromiseResponse = jest.fn().mockReturnValue(Promise.resolve(true));
const putFn = jest.fn().mockImplementation(() => ({promise: awsSdkPromiseResponse}))
return {
put: putFn,
get: putFn,
delete: putFn,
batchGet: putFn,
batchWrite: putFn,
query: putFn,
scan: putFn,
update: putFn,
transactGet: putFn,
transactWrite: putFn
}
})
return { DocumentClient: documentClient };
});
});
test('AWS.DynamoDB is called', async() => {
await sut.putItem({
TableName: 'test',
Item: {
pk: 'test_pk',
sk: 'test_sk',
email: 'test@test.com'
}
})
expect(DynamoDB).toHaveBeenCalledTimes(1)
})

运行此测试会给我一个错误,如下所示:

TypeError: _dynamodb.default.DocumentClient is not a constructor

DocumentClient似乎是位于命名空间DynamoDB中的一个静态属性,而我在上面的DynamoDB模型中试图做的是将DocumentClient定义为DynamoDB类的实例属性。我知道这是不对的,我在互联网上搜索过类似的东西,但找不到任何东西。

问题还在于,我想在测试文件中模拟DynamoDBDocumentClient类的构造函数。我发现了一篇与我想做的类似的文章,但这里的手动嘲讽也于事无补。通过这种方式,我无法同时模拟DynamoDBDocumentClient的构造函数

我对TypeScript很陌生,也许我在做一些完全愚蠢的事情。任何建议都将不胜感激!

这可能有助于

const dynamoPromise = jest.fn();
jest.mock('aws-sdk/clients/dynamodb', () => {
const originalModule = jest.requireActual('aws-sdk/clients/dynamodb');
// Mock the default export and named export 'foo'
return {
__esModule: true,
...originalModule,
DocumentClient: jest.fn(() => ({
batchWrite: jest.fn().mockImplementationOnce(() => ({
promise: jest.fn().mockImplementationOnce(dynamoPromise),
})),
})),
};
});
//later in a test case
dynamoPromise.mockImplementationOnce(() => Promise.reject(new Error('For testing purposes DynamoDB fails.')));

最新更新