🐬

TypeScript な Node.js + Jest でテスト毎に DB(MySQL) をリセットする関数

2021/11/25に公開

まずは MySQL クライアントをインストールします。
繋がればなんでもいいので一番スター数が多くて型定義もあるこちらにしました。
https://github.com/mysqljs/mysql

npm install --save-dev mysql @types/mysql

まずは DB を破壊して再生します。

import { createConnection } from "mysql";
import * as fs from "fs";

export async function resetDB() {
  const connection = createConnection({
    host: "localhost",
    user: "root",
    password: "",
    multipleStatements: true,
  });
  connection.connect();
  connection.query("DROP DATABASE IF EXISTS test_db");
  connection.query("CREATE DATABASE test_db");
  connection.query("use test_db");

次に初期データを入れます。
ここはどうやってテスト用のデータを管理しているかによって変わりますが、今回私の場合は dump された SQL ファイルがあったので、それを読み込んで実行するようにしました。

  // test.dump を初期データとして入れるよ
  const seedSQLFile = fs.readFileSync(
    "./docker/compose/db/init/test.dump",
    "utf8"
  );
  const queries = seedSQLFile.split(";");
  for (const query of queries) {
    await new Promise<void>((resolve) =>
      connection.query(query).on("result", resolve)
    );
  }

最後に忘れずにコネクションを閉じれば完成です。

  connection.end();
}

Jest ではそれぞれのテスト前に実行するようにします。beforeEach は次のように書きます。ちゃんと await しないと reset 処理を待たずにテストが走ってしまうので気をつけましょう☝️

beforeEach(async () => {
  await resetDB();
});

Discussion