Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
557 views
in Technique[技术] by (71.8m points)

amazon web services - Jest & AWS.DynamoDB.DocumentClient mocking

I'm trying to mock a call to AWS.DynamoDB.DocumentClient. I tried several solutions I found online, but I cannot get it to work.

This is my best effort so far:

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);
    });
  });
});

I get error message

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

My source file:

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;
  }
}

Please advise how can I properly mock the response of AWS.DynamoDB.DocumentClient.update

question from:https://stackoverflow.com/questions/65870436/jest-aws-dynamodb-documentclient-mocking

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Have some way to do the that thing (I think so).

This is one of them:

You use AWS.DynamoDB.DocumentClient, then we will mock AWS object to return an object with DocumentClient is mocked object.

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

Now, AWS.DynamoDB.DocumentClient is mocked obj. Usage of update function like update(params).promise() => Call with params, returns an "object" with promise is a function, promise() returns a Promise. Do step by step.

      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 to check the update will be call or not, updatePromiseMocked to control result of update function (success/ throw error).

Complete example:

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);
    });
  });
});


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...