2
0

More than 1 year has passed since last update.

jest.mock + prototypeでDynamoDBをMock化した

Posted at

そもそもやりたかったこと

SQSから受け取ったメッセージを lambdaで加工し、
その情報を使ってDynamoDBからItemをGet、指定のURLへItemの内容をaxiosを使ってPostする仕組みを作っていました。

テストコードを記述するにあたり DynamoDB.DocumentClient.get部分をMock化したいと思いました。
ググるとaws-sdk-mock とか、aws-sdk-client-mockとか情報が出てくるのですがうまくMock化できず詰まりました。
aws-sdk-client-mockはそもそも使っているAWS SDKがv2だったので使えなそうと思い断念。

最終的に jest.mock + JavaScriptのprototypeの組み合わせでうまく行ったので、備忘のため記述します。

環境

lambda: typescript(4.1.3)
テストFW: jest(27.4.7)
aws-sdk: 2.1070.0

mock化したいサンプルコード

 sample.ts
import * as AWS from 'aws-sdk';
import { AWSError } from 'aws-sdk';
import { DocumentClient } from 'aws-sdk/clients/dynamodb';
import { PromiseResult } from 'aws-sdk/lib/request';

export const documentClientConfig: AWS.DynamoDB.Types.ClientConfiguration = {
  apiVersion: '2012-08-10',
};
export class DDB {
  public static async findById(id: string): Promise<PromiseResult<DocumentClient.GetItemOutput, AWSError>> {
    const condition: DocumentClient.GetItemInput = {
      TableName: 'table_name',
      Key: {
        ID: id,
      },
    };
    const documentClient: DocumentClient = new AWS.DynamoDB.DocumentClient(documentClientConfig);
    return documentClient.get(condition).promise();
  }
}

テストコード

sample.test.ts
import AWS from 'aws-sdk';
import { Handler } from 'path_to_handler/handler';

jest.mock('aws-sdk');   // aws-sdkのMock化。この記述がないとできない

describe('test', () => { 
    beforeEach(() => {
      const ddbData = {
        Item: { ID: '1', Data: 'XXX' },
      };

      const mockDynamoDbGet = {
        promise: () => {
          return ddbData;
        },
      };
      // Document.Client.getのMock化 .prototypeがポイント
      const getMock = AWS.DynamoDB.DocumentClient.prototype.get as jest.Mock;
      // Getのレスポンスが返す値を注入。
      jest.mocked(getMock).mockReturnValue(mockDynamoDbGet);
    });
    it('handlerのテスト', async () => {
      const event = {id: '1'};
      const result = await new Handler(event).execute();
      expect(result.ID).toEqual('1'); 
      expect(result.Data).toEqual('XXX'); 
    }); 
  });

まとめ

Mock化したいコンストラクタのprototypeを使うことで解決しました!

prototypeでAWS.DynamoDB.DocumentClientにgetメソッドを持たせて、
getのレスポンスに期待値を注入しています。

prototypeについてはこちらがわかりやすかったです。

終わってみればたった数行で、簡単にDynamoDBのGetがMock化できました。

2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0