LoginSignup
4
2

More than 1 year has passed since last update.

Middyを利用したLambda関数のhandlerをテストする

Posted at

概要

Serverless Frameworkのaws-nodejs-typescriptを導入して、Middyを利用したLambda関数を作成しました。
その単体テストを作成する際に他に同じようなことをしている方のリポジトリを見つけることができず、ハマったのでメモです。

Middyとは?

簡単に説明すると、MiddyはLambdaで使える軽量なミドルウェアエンジンです。
バリデーション処理やロギングなど、様々な共通処理をMiddyに任せることで
業務ロジックだけに専念することができることがメリットです。
詳細はドキュメントを参照ください。

前提

Serverless FrameworkでNode.jsとTypeScriptを利用したテンプレートである
aws-nodejs-typescriptを利用しています。
ここに既にMiddyが導入されています。

Jestを導入する

以下コマンドでJestをインストール
npm install jest ts-jest @types/jest -D

設定ファイルを用意します。

jest.config.js
module.exports = {
  preset: 'ts-jest',
  roots: ['<rootDir>/src/__tests__'],
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
  moduleNameMapper: {
    '^@src/(.*)$': '<rootDir>/src/$1',
    '^@libs/(.*)$': '<rootDir>/src/libs/$1',
    '^@functions/(.*)$': '<rootDir>/src/functions/$1'
  },
  testMatch: ['**/__tests__/**/*.+(ts|js)', '**/?(*.)+(spec|test).+(ts|js)'],
  collectCoverageFrom: ['src/**/*.{js,ts}', '!**/node_modules/**', '!**/vendor/**'],
  coveragePathIgnorePatterns: ['src/__tests__/', 'src/types/'],
};

テストフォルダ作成

src直下に__test__というディレクトリを作成し、その中にテストファイルを配置します。
テストファイル名はXXX.spec.tsまたはXXX.test.tsとします。

テストコードを作成する

src/functions/hello/hello.ts
import { formatJSONResponse } from '@libs/api-gateway';
import { middyfy } from '@libs/lambda';

const hello = async (event: any) => {
  return formatJSONResponse({
    message: `Hello ${event.body.name}, welcome to the exciting Serverless world!`
  });
};

export const main = middyfy(hello);

上記のようなLambda handlerに対してテストを用意する際は以下のようにします。

src/__tests__/hello.spec.ts
jest.mock('@libs/lambda', () => ({
    middyfy: jest.fn((handler) => handler),
}));

import { main } from '@functions/hello/handler';

const event: any = {
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "name": "Frederic"
  }
}

describe('hello関数のテスト', () => {
    test('正しいレスポンスを返す', async () => {
        const context: any = undefined
        const actual = await main(event, context);

        const expected = {
            body: JSON.stringify({
                message: `Hello ${event.body.name}, welcome to the exciting Serverless world!`
            }),
            statusCode: 200
        };

        expect(actual).toEqual(expected);
    });
});

本来TypeScriptの適切な型を定義すべきですが、無理やり通してしまっているためcontext変数などの定義を行っています。

実際にはhandlerのexport値に対してmiddyfyされているため、テストを作成する方法に悩みましたが、最初の3行のようにモック化させることでhandler内のテスト作成ができました。

npx jestでテスト実行できます。
package.jsonに記載してnpm testとすることもできます。

テストデータをJSONファイルに切り出す

tsconfig.jsoncompilerOptions"resolveJsonModule": true設定することでJSONモジュールを読み込めるようになります。
event.bodyの値をJSONファイルに切り出してテストデータを作れます。

その他

以下のようなSererless Frameworkのドキュメント内に以下のテストライブラリも紹介されていましが、そんなに有名でない&普通にJestをインストールすることと大差ないと判断しました。

4
2
0

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
4
2