Claudia.jsでデプロイと単体テストを実行してみた

2019.09.26

こんにちは。Node.js勉強中の坂井です。

Node.jsでWeb APIを実装する時に、どのように開発していますか? 個々のリソースの作成をAWSマネジメントコンソールやAWS CLIから作成する、サーバーレスアプリケーションフレームワークやツールを利用するなどいろいろな手段があると思います。 今回はその中から、Claudia.jsを利用して、Web APIの実装ローカル環境でのテストをやってみたいと思います。

過去にもClaudia.jsを紹介した弊社ブログがありますので、合わせてご確認ください。

Claudia.js を使った簡単マイクロサービス開発

環境

  • macOS Mojave 10.14.6
  • Node.js 8.16.1
  • npm 6.4.1
  • AWS CLI 1.16.220

事前準備

インストールと確認

以下のコマンドを実行して、インストールします。

$ npm install claudia -g

$ claudia --version
5.8.0

プロジェクトの作成

公式サンプルにしたがって、簡単なプロジェクトを作成してみます。 必要なファイルを作成します。

package.json

{
  "name": "web-api-test",
  "files": [
    "*.js"
  ],
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "claudia-api-builder": "^4"
  },
  "main": "web.js",
  "version": "1.0.0"
}

web.js

var ApiBuilder = require("claudia-api-builder"), 
	api = new ApiBuilder();
module.exports = api;

api.get("/hello", function() {
    "use strict";
    return "hello world";
});

api.get("/echo/{id}", function(request) {
    "use strict";
    return request.pathParams.id;
});

ファイルを作成し、以下のコマンドを実行し、パッケージをインストールします。

$ npm install

この時点で以下のようなディレクトリ構成となります。

[作業ディレクトリ]
├── node_modules
├── package-lock.json
├── package.json
└── web.js

AWSへデプロイ

以下のコマンドを実行し、デプロイします。

$ claudia create --name web-api-test --region ap-northeast-1 --api-module web
{
  "lambda": {
    "role": "web-api-test-executor",
    "name": "web-api-test",
    "region": "ap-northeast-1"
  },
  "api": {
    "id": "XXXXXXXXXX",
    "module": "web",
    "url": "https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/latest"
  }
}

レスポンスに含まれるURLとリソースのパスを組み合わせたURLを、ブラウザやCURLコマンドで実行すると、デプロイされていることを確認できます。

$ curl https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/latest/hello
"hello world"

また、実装を更新してデプロイする場合は、以下のコマンドでデプロイできます。

$ claudia update
updating REST API       apigateway.setAcceptHeader
{
  "FunctionName": "web-api-test",
  …

Lambda関数、API Gatewayがデプロイされ、リソースが作成されていることを確認できました。 また、LambdaにアタッチするIAMロールも自動で作成されました。 ここまで自動で作成されるのは、助かりますね。

単体テスト

Lambda関数の単体テストの実行については、なかなか難しいと感じているのですが、 公式ページに単体テストの実行例がありましたので、Web APIを実際にテストしてみたいと思います。

実行例では、Jasmineを利用しているようでしたので、Jasmineをセットアップしてテストを実行してみます。

Jasmineをインストール

以下のコマンドを実行してインストール、セットアップを実行します。

$ npm install jasmine
$ node node_modules/jasmine/bin/jasmine init

package.jsonに以下のスクリプトを追加

"scripts": { "test": "jasmine" }

テストコードを作成

/hello/echo/{id} の返却値を検証するテストを実装します。

web_spec.js

var underTest = require("../web.js");

describe("Web API Test", () => {
    var lambdaContextSpy;

    beforeEach(() => {
        lambdaContextSpy = jasmine.createSpyObj("lambdaContext", ["done"]);
    });

    it("Hello Worldがreturnされること", done => {
        underTest
            .proxyRouter(
                {
                    requestContext: {
                        resourcePath: "/hello",
                        httpMethod: "GET"
                    }
                },
                lambdaContextSpy
            )
            .then(() => {
                expect(lambdaContextSpy.done).toHaveBeenCalledWith(null, jasmine.objectContaining({ body: '"hello world"' }));
            })
            .then(done, done.fail);
    });

    it("パラメータの値がそのままreturnされること", done => {
        underTest
            .proxyRouter(
                {
                    requestContext: {
                        resourcePath: "/echo/{id}",
                        httpMethod: "GET"
                    },
                    pathParameters: {
                        id: "123"
                    }
                },
                lambdaContextSpy
            )
            .then(() => {
                expect(lambdaContextSpy.done).toHaveBeenCalledWith(null, jasmine.objectContaining({ body: '"123"' }));
            })
            .then(done, done.fail);
    });
});

テストを実行

以下のコマンドでテストを実行します。

npm test

Started
..
2 specs, 0 failures
Finished in 0.015 seconds

わかりにくいですが、. がテスト結果です。 2パターンのテストが成功しました。

さいごに

実際に触ってみて、Web API開発時にリソース一式のデプロイをコマンドで実行することができるので、とても便利に感じました。 また、公式のチュートリアルにテストについて記載されており、CIのイメージもつきやすいと思いました。 今回は基本的な部分しか触れてませんが、もう少し実践的な部分も今後触っていきたいと思います。

参考