【问题标题】:How to mock dynamoDB call with jest?如何用玩笑模拟 dynamoDB 调用?
【发布时间】:2021-11-27 05:37:27
【问题描述】:

我有一个简单的处理程序,调用 getData 在单独的文件中定义

export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
  let respData = await new DynamoDBClient().getData(123);
  return {
    statusCode: 200,
    body: JSON.stringify(respData),
  };
};

在我的 DynamoDB 类中,我有以下内容。

import { DynamoDB } from 'aws-sdk';
export default class DynamoDBClient {
private config: Config;
private client: DynamoDB.DocumentClient;

constructor() {
  this.config = getConfig();

  const dynamoDBClientConfig = this.config.mockDynamoDBEndpoint
  ? {
      endpoint: this.config.mockDynamoDBEndpoint,
      sslEnabled: false,
      region: 'local'
    }
  : undefined;

 this.client = new DynamoDB.DocumentClient(dynamoDBClientConfig);
}
// function
getData= async (id: string): Promise<any> => {
 const response = await this.client
  .query({
    TableName: tableName,
    IndexName: tableIndex,
    KeyConditionExpression: 'id= :id',
    ExpressionAttributeValues: {
      ':id': id
    }
  })
  .promise();
 return response;
}
}

我的测试用例

describe('DynamoDB', () => {
test('should return no data', async () => {
    
    const spy = jest.spyOn(DynamoDBClient, 'getData').mockImplementation(() => jest.fn(() => {
      return Promise.resolve({});
  }));
    const actual = await handler(event);
    console.log(actual);

    expect(actual).toEqual({ statusCode: 400, body: JSON.stringify({ }) });
  });
 });

【问题讨论】:

    标签: typescript unit-testing testing jestjs amazon-dynamodb


    【解决方案1】:

    您使用属性初始化语法定义了.getData() 方法。它将绑定到类实例。由于handler函数通过import语句依赖于DynamoDBClient类,所以不能在测试用例中创建实例并在调用时将其传递给handler

    您可以模拟 aws-sdk 模块和 DynamoDB.DocumentClient 类及其实例。

    DynamoDBClient.ts:

    import { DynamoDB } from 'aws-sdk';
    
    function getConfig() {
      return { mockDynamoDBEndpoint: '' };
    }
    interface Config {
      mockDynamoDBEndpoint: string;
    }
    
    export default class DynamoDBClient {
      private config: Config;
      private client: DynamoDB.DocumentClient;
    
      constructor() {
        this.config = getConfig();
    
        const dynamoDBClientConfig = this.config.mockDynamoDBEndpoint
          ? {
              endpoint: this.config.mockDynamoDBEndpoint,
              sslEnabled: false,
              region: 'local',
            }
          : undefined;
    
        this.client = new DynamoDB.DocumentClient(dynamoDBClientConfig);
      }
    
      getData = async (id: string): Promise<any> => {
        const response = await this.client
          .query({
            TableName: 'tableName',
            IndexName: 'tableIndex',
            KeyConditionExpression: 'id= :id',
            ExpressionAttributeValues: {
              ':id': id,
            },
          })
          .promise();
        return response;
      };
    }
    

    handler.ts:

    import DynamoDBClient from './DynamoDBClient';
    
    interface APIGatewayProxyEvent {}
    interface APIGatewayProxyResult {}
    
    export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
      let respData = await new DynamoDBClient().getData('123');
      return { statusCode: 200, body: JSON.stringify(respData) };
    };
    

    handler.test.ts:

    import { handler } from './handler';
    import { DynamoDB } from 'aws-sdk';
    
    const mDocumentClientInstance = {
      query: jest.fn().mockReturnThis(),
      promise: jest.fn(),
    };
    jest.mock('aws-sdk', () => {
      return {
        DynamoDB: {
          DocumentClient: jest.fn(() => mDocumentClientInstance),
        },
      };
    });
    
    describe('69475890', () => {
      afterEach(() => {
        jest.clearAllMocks();
      });
      test('should pass', async () => {
        mDocumentClientInstance.promise.mockResolvedValueOnce({});
        const event = {};
        const actual = await handler(event);
        expect(actual).toEqual({ statusCode: 200, body: JSON.stringify({}) });
        expect(DynamoDB.DocumentClient).toBeCalled();
        expect(mDocumentClientInstance.query).toBeCalledWith({
          TableName: 'tableName',
          IndexName: 'tableIndex',
          KeyConditionExpression: 'id= :id',
          ExpressionAttributeValues: {
            ':id': '123',
          },
        });
        expect(mDocumentClientInstance.promise).toBeCalled();
      });
    });
    

    测试结果:

     PASS  examples/69475890/handler.test.ts (8.642 s)
      69475890
        ✓ should pass (4 ms)
    
    -------------------|---------|----------|---------|---------|-------------------
    File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -------------------|---------|----------|---------|---------|-------------------
    All files          |     100 |       50 |     100 |     100 |                   
     DynamoDBClient.ts |     100 |       50 |     100 |     100 | 18                
     handler.ts        |     100 |      100 |     100 |     100 |                   
    -------------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        9.231 s
    

    【讨论】:

      猜你喜欢
      • 2018-05-05
      • 2020-03-15
      • 2021-11-04
      • 1970-01-01
      • 2021-01-06
      • 2020-02-08
      • 1970-01-01
      • 2022-10-06
      • 2020-12-17
      相关资源
      最近更新 更多