GitHub
前提条件
配列を仮想DBとした掲示板APIサーバの作成(1/5):はじめに・環境構築・DB、コメントモデルの作成
実装する機能
「GET/api/comments」リクエストを送ると、コメント一覧がレスポンス値として返ってくる
この記事のまとめ
- DB内のコメントを会得するメソッドを作成した
- GETリクエストした時のメソッドを作成した。
コメント一覧を返すメソッド(findAll)
module.exports = {
  findAll: () => {
    return comments;
  }
};
module.exports内にcommentsのデータを返すメソッドを作成します。これで外にコメント一覧を返すことができます。
それでは、このfindAllメソッドがきちんと働いているかテストしてみます。
findAllのテスト
まずは、テストに必要なライブラリのインストールを行います。
- mocha:テスト用のフレームワークです。
mochaはtestディレクトリ直下にあるjsファイルを自動で実行してくれますが、APIリクエスト用とモデル用のテストファイルはディレクトリ内で分けようと思っているので、mocha.optsという設定用ファイルをtestディレクトリ内に作成し、以下のオプションを設定します。
--recursive
これで、testディレクトリ内でさらにディレクトリを作成、ファイルを分けてもテストが実行されるようになりました。
それと、eslintも、そのままだとmochaに依存しているライブラリがnot definedとなるので、以下のコマンドを追加します。
"env": {
  "mocha": true
},
- power-assert:値を比較するためのアサーションライブラリです。基本的にはテストフレームワークと併用します。
テストの内容
今回のテストで知りたい内容は
- 
findAllはメソッドである
- 
findAllで返されるデータは配列である
- 
findAll実行後、配列内に適切にデータが格納されている
この3点を確認するコードを記述します。
const assert = require('power-assert');
const Comment = require('../../models/Comment');
describe('comment.findAllのテスト', () => {
  const comments = Comment.findAll();
  // describe内に以下のテストコードを記述していきます
});
describe,it:mochaのテスト用メソッドです、こちらのメソッド内にテストコードを記述します。
- 
findAllはメソッドである
const comments = Comment.findAll();
it('findAllはメソッドである', () => {
  assert.equal(typeof Comment.findAll, 'function');
});
typeof演算子でfindAllがメソッド、関数オブジェクトであるかどうかテストします。
ここでassertを使い、第一引数と第二引数が等しいかどうか判別できます
- 
findAllで返されるデータは配列である
it('commentsは配列である', () => {
  assert.equal(Array.isArray(comments), true);
});
Array.isArray()メソッドで、findAllで返されたデータが配列であるかテストします。
配列であるならtrueが返ってくるはずなので、第二引数にtrueを入れます
- 
findAll実行後、配列内に適切にデータが格納されている
it('commentsには適切にデータが格納されている', () => {
  comments.forEach(comment => {
    assert.deepEqual(comment, {
      id: comment.id,
      username: comment.username,
      body: comment.body,
      createdAt: comment.createdAt,
      updatedAt: comment.updatedAt,
    });
  });
});
assert.deepEqual()メソッドで、commentクラス内部のプロパティ値は適切かどうかをテストします(idプロパティにbodyの値が入っていたりするとよくないので)
これらのテストがすべて成功することを確認したら、次はAPIリクエストをした時に、コメント一覧が返ってくるようコーディングします。
comments.js(controller)の作成
MVC構想でのControllerの機能を司るファイルです。ここで書いたメソッドは後述するルーティング用ファイル経由で実行します。
GETリクエスト時に動作するメソッドの作成(getComment())
const Comment = require('../models/Comment');
module.exports = {
  getComment: (req, res) => {
    const storedComments = Comment.findAll();
    res.status(200).json(storedComments);
  },
};
Comment.findAll()を実行後、得たデータをjson形式で渡します、その際にステータスコード200(通信成功)も一緒に渡します。
comments.js(routers)の作成
こちらでControllerのメソッドを読み込み、各HTTPリクエストが行われた際の紐付けを行います
const express = require('express');
const router = express.Router();
const controller = require('../controller/comments');
router.route('/').get(controller.getComment);
module.exports = router;
- GETリクエストが来た場合の動作の実装
 Controller.getCommentメソッドを実行します、実行した際のデータはmodule.exportsで外部に渡します
app.jsの作成
const express = require('express');
const router = require('./routers/comments');
const app = express();
app.use('/api/comments', router);
module.exports = app;
PORT/api/commentsアドレスにアクセスした際の動きを記述していますが、こちらのファイルで直接実行せず、後述のindex.jsでサーバー起動を行いますので(1つの機能ごとにファイルを分けられるなら分けていったほうが後々のコード確認や修正も行いやすいので)module.exportsで外に渡します
index.jsの作成
こちらでポート番号を指定後、app.jsから渡されたデータを読み込み、サーバ起動を行います。
const app = require('./app');
const PORT = 8050;
app.listen(PORT, function() {
  console.log(`Example app listening on port ${PORT}`);
});
サーバー起動し、動作は正常か確認する
nodemon経由でindex.jsの起動後、ブラウザから8050/api/commentsにアクセスします。
nodemon:指定したファイルを更新するたびにサーバーを自動で再起動してくれるライブラリです
 
コメント一覧がjson形式で表示されたのでGETリクエストした際の実装は成功しました。
次に、本当にサーバー側での挙動は問題ないかテストを行いたいと思います。
getComment()のテスト
まずは、テストに必要なライブラリのインストールを行います。
- supertest:APIの挙動の確認をテストできるライブラリです
テストの内容
- 
api/todosからGETリクエストを行なった際に、json形式でデータを渡している
- jsonデータの内部は適切である
この3点を確認するコードを記述していきます
const request = require('supertest');
const assert = require('power-assert');
const app = require('../../../app');
describe('test 「GET /api/comments」', () => {
  it('GETリクエストで返されたデータは適切である', async () => {
    //以下のテストコードを記述していきます
  });
});
- 
api/todosからGETリクエストを行なった際に、json形式でデータを渡している
const response = await request(app)
  .get('/api/comments')
  .expect('Content-Type', /json/)
  .expect(200);
supertestは内部で擬似的にサーバ起動を行います。
getリクエスト後、.expectでデータがjsonであることとステータスコードが200で渡されていることを確認します。
- jsonデータの内部は適切である
const comments = response.body;
assert.equal(Array.isArray(comments), true);
comments.forEach(comment => {
  assert.equal(typeof comment.id, 'number');
  assert.equal(typeof comment.username, 'string');
  assert.equal(typeof comment.body, 'string');
  assert.equal(typeof comment.createdAt, 'string');
  assert.equal(typeof comment.updatedAt, 'string');
});
json内部のデータは配列であることを確認し、配列に格納されているデータは適切かどうかチェックします。
これらのテストが完了したら、「「GET/api/comments」リクエストを送ると、コメント一覧がレスポンス値として返ってくる」の実装は完了です。
現在の構成
.
├── README.md
├── app.js
├── controller
│   └── comments.js
├── index.js
├── models
│   └── Comment.js
├── package-lock.json
├── package.json
├── routers
│   └── comments.js
└── test
    ├── app
    │   └── api
    │       └── getComment.test.js
    ├── mocha.opts
    └── models
        └── findAll.test.js
次は「「POST/api/comments」リクエストを送ると、新規にComment1件を作成し、作成されたCommentがレスポンス値として返ってくる」機能の実装です。