Jest で Express と Mongoose をまとめてテストするやつでちょっと探すの苦労したのでまとめてメモ書き。
なんかいろいろググった結果この記事を一番参考にした。
とりあえず必要な開発用パッケージをインストールします。
npm i -D mongodb-memory-server
mongodb
の代わりにmongodb-memory-server
が動くようにするためにテスト用に db ファイルを作成します。
/___tests__/config/database.ts
import mongoose from "mongoose";
import { MongoMemoryServer } from "mongodb-memory-server";
import { MongoClient } from "mongodb";
let connection: MongoClient;
let mongoServer: MongoMemoryServer;
const connect = async () => {
mongoServer = await MongoMemoryServer.create();
connection = await MongoClient.connect(mongoServer.getUri(), {});
};
const close = async () => {
await mongoose.connection.dropDatabase();
await mongoose.connection.close();
await mongoServer.stop();
};
const clear = async () => {
const collections = mongoose.connection.collections;
for (const key in collections) {
await collections[key].deleteMany({});
}
};
export default { connect, close, clear };
実際はあえて途中でclear
しないことでそのまま他のメソッドのリクエストも続けて書いたりしました。
本当はそれぞれ分けて書いたほうがいいんだろうけど。
/___tests__/tags.test.ts
import request from "supertest";
import app from "../src/index";
import db from "./config/database";
const agent = request.agent(app);
beforeAll(async () => await db.connect());
afterEach(async () => await db.clear());
afterAll(async () => await db.close());
describe("tags", () => {
let tag = { name: "test-tag", id: undefined };
describe("POST /tags", () => {
test("successful", async () => {
const res = await agent.post("/tags").send(tag);
expect(res.statusCode).toEqual(201);
tag.id = res.body.id;
expect(res.body).toEqual(expect.objectContaining(tag));
});
});
});
ちなみにポートが戦ってしまったので、テストのときはアプリを立ち上げないようにした。
package.json
"scripts": {
"test": "export NODE_ENV=test && jest --forceExit --runInBand",
},
/src/index.ts
if (process.env.NODE_ENV !== "test") {
app.listen(port, () => {
console.log(`Express app listening at ${process.env.BASE_URI}:${port}`);
});
}
全体的に割と読めばわかるというか、大したことはしていないけど正直いろんなドキュメント見て回らないと書けないなあと思ったのでメモ。 多分コピペすれば動くと思う。