【问题标题】:Mocking DynamoDB.DocumentClient's constructor with Jest and Typescript用 Jest 和 Typescript 模拟 DynamoDB.DocumentClient 的构造函数
【发布时间】:2021-04-05 21:42:05
【问题描述】:

在我的 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 开发工具包函数。但是,我在模拟 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 类的构造函数。我发现article 类似于我正在尝试做的事情,但这里的手动模拟也无济于事。通过这个,我无法模拟 DynamoDBDocumentClient 的构造函数

我对 TypeScript 很陌生,也许我正在做一些完全愚蠢的事情。任何指针表示赞赏!

【问题讨论】:

    标签: typescript unit-testing jestjs aws-sdk-js


    【解决方案1】:

    这可能对你有帮助

    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.')));

    【讨论】:

      猜你喜欢
      • 2020-01-08
      • 2020-05-06
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      • 2022-07-22
      • 2019-08-19
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多