このドキュメントについて。
TypeScriptで書かれたExpressの簡単なファイルをJestで書いたもののメモです。
タイトルの3つの技術についての解説は行いません。
書いたコードの解説
試したかったことは、Jestのmock機能です。
TypeScript + Expressで実装された、モジュールをimportしている関数を用意します。
そのモジュールをJestの機能でmock化し、関数のユニットテストを書くサンプルです。
テスト対象コード
Expressのルーターから呼ばれるgetJson.ts
です。
受け取ったreq
のreq.query.price
をaddYen.exec
に渡し、返り値をJSON形式に詰めて返しています。
こちらのテストを書きます。
import * as express from 'express'
import * as addYen from "./addYen";
export default (req: express.Request, res: express.Response, next?: express.NextFunction) => {
const yenPrice: string = addYen.exec(req.query.price);
res.json({ price: yenPrice });
}
テスト対象がimportしているコード
getJson.ts
がimportしているaddYen.ts
です。
引数に「円」を付けて返すだけの関数exec
を持っています。
export function exec (req: string){
return req + " 円";
}
これらを準備したら、テストコードを書きます。
テストコード
import { mockReq, mockRes } from "sinon-express-mock";
// テスト対象がimportしているモジュールをモック化する
jest.mock('../src/addYen', () => ({
exec: jest.fn(() => `100 円`),
}));
// モックを読み込み
const addYen = require('../src/addYen');
// テスト対象を読み込み
import getJson from "../src/getJson";
describe("getJson", () => {
it("正常に処理が終了する", () => {
// Expressのrequestオブジェクトとresponseオブジェクトをモック化
const request = {
query: {
price: "100"
}
};
const req = mockReq(request);
const res = mockRes();
// テスト対象を実行
getJson(req, res);
// addYen.exec()が引数request.query.priceで実行されていることを検証
expect(addYen.exec).toBeCalledWith(request.query.price);
// addYen.exec()が1度だけ実行されていることを検証
expect(addYen.exec.mock.calls.length).toBe(1);
});
});
ディレクトリ構成は以下のようになっています。
├── src
│ ├── addYen.ts
│ └── getJson.ts
├── test
│ └── getJson.test.ts
ひとまずやりたかったことはできました。
やってみての疑問
Jestの機能
今回テストコードの中で、Expressのrequestオブジェクトとresponseオブジェクトをモック化するためにsinon-express-mock
をimportしましたが、Jestにそういった機能があるかは調べていませんので、もしかしたらJestだけで今回のテストコードが書けるかも、、?
supertest的なこともできるのかな?
requireとimportの違い
テストコードでのモック読み込み部分ですが、importではうまくいかなかったのですが、requireにすることで実行できました。
requireとimportについて、もっと中身を知らないと。。
// モックを読み込み
// requireでは動いて、
const addYen = require('../src/addYen');
// importでは動かなかった。。
import * as addYen from '../src/addYen';