有 & AWS.DynamoDB.DocumentClient 嘲笑

Jest & AWS.DynamoDB.DocumentClient mocking

我正在尝试模拟对 AWS.DynamoDB.DocumentClient 的调用。我尝试了在网上找到的几种解决方案,但无法正常工作。

这是我迄今为止的最大努力:

import * as AWS from 'aws-sdk';
import * as dynamoDbUtils from '../../src/utils/dynamo-db.utils';

jest.mock("aws-sdk");

describe('dynamo-db.utils', () => {
  describe('updateEntity', () => {
    it('Should return', async () => {
      AWS.DynamoDB.DocumentClient.prototype.update.mockImplementation((_, cb) => {
        cb(null, user);
      });
      await dynamoDbUtils.updateEntity('tableName', 'id', 2000);
    });
  });
});

我收到错误消息

Property 'mockImplementation' does not exist on type '(params: UpdateItemInput, callback?: (err: AWSError, data: UpdateItemOutput) => void) => Request<UpdateItemOutput, AWSError>'.ts(2339)

我的源文件:

import AWS from 'aws-sdk';

let db: AWS.DynamoDB.DocumentClient;

export function init() {
  db = new AWS.DynamoDB.DocumentClient({
    region: ('region')
  });
}

export async function updateEntity(tableName: string, id: string, totalNumberOfCharacters: number): Promise<AWS.DynamoDB.UpdateItemOutput> {
  try {
    const params = {
      TableName: tableName,
      Key: { 'id': id },
      UpdateExpression: 'set totalNumberOfCharacters = :totalNumberOfCharacters',
      ExpressionAttributeValues: {
        ':totalNumberOfCharacters': totalNumberOfCharacters
      },
      ReturnValues: 'UPDATED_NEW'
    };

    const updatedItem = await db.update(params).promise();

    return updatedItem;
  } catch (err) {
    throw err;
  }
}

请告知我如何才能正确模拟 AWS.DynamoDB.DocumentClient.update

的响应

有办法做那件事(我想是的)。

这是其中之一:

您使用AWS.DynamoDB.DocumentClient,那么我们将模拟AWS对象到return具有DocumentClient的对象是模拟对象。

jest.mock("aws-sdk", () => {
  return {
    DynamoDB: {
      DocumentClient: jest.fn(),
    },
  };
});

现在,AWS.DynamoDB.DocumentClient 是模拟对象。更新函数的用法,如 update(params).promise() => 用 params 调用,returns 一个带有 promise 的“对象”是一个函数,promise() return这是一个承诺。循序渐进。

      updateMocked = jest.fn();
      updatePromiseMocked = jest.fn();

      updateMocked.mockReturnValue({
        promise: updatePromiseMocked,
      });

      mocked(AWS.DynamoDB.DocumentClient).mockImplementation(() => {
        return { update: updateMocked } as unknown as AWS.DynamoDB.DocumentClient;
      });

mocked import from ts-jest/utils, updateMocked 检查 update 是否调用, updatePromiseMocked 控制 [=24= 的结果] 函数(成功/抛出错误)。

完整示例:

import * as AWS from 'aws-sdk';
import * as dynamoDbUtils from './index';
import { mocked } from 'ts-jest/utils'

jest.mock("aws-sdk", () => {
  return {
    DynamoDB: {
      DocumentClient: jest.fn(),
    },
  };
});

describe('dynamo-db.utils', () => {
  describe('updateEntity', () => {
    let updateMocked: jest.Mock;
    let updatePromiseMocked: jest.Mock;
    beforeEach(() => {
      updateMocked = jest.fn();
      updatePromiseMocked = jest.fn();

      updateMocked.mockReturnValue({
        promise: updatePromiseMocked,
      });

      mocked(AWS.DynamoDB.DocumentClient).mockImplementation(() => {
        return { update: updateMocked } as unknown as AWS.DynamoDB.DocumentClient;
      });

      dynamoDbUtils.init();
    });

    it('Should request to Dynamodb with correct param and forward result from Dynamodb', async () => {
      const totalNumberOfCharacters = 2000;
      const id = 'id';
      const tableName = 'tableName';
      const updatedItem = {};


      const params = {
        TableName: tableName,
        Key: { 'id': id },
        UpdateExpression: 'set totalNumberOfCharacters = :totalNumberOfCharacters',
        ExpressionAttributeValues: {
          ':totalNumberOfCharacters': totalNumberOfCharacters
        },
        ReturnValues: 'UPDATED_NEW'
      };
      updatePromiseMocked.mockResolvedValue(updatedItem);

      const result = await dynamoDbUtils.updateEntity(tableName, id, totalNumberOfCharacters);

      expect(result).toEqual(updatedItem);
      expect(updateMocked).toHaveBeenCalledWith(params);
    });
  });
});