この記事では、Next.jsとPrismaを使って開発をしているプロジェクトで「データベースを使ったテスト」を導入するまでの流れを分かりやすく解説します。
Prismaを使った開発をしている方の参考になれば幸いです。
- Node:v18.9.0
- Prisma:4.4.0
- React:18.1.0
- Jest:28.1.0
- TypeScript:4.6.4
- MySQL:8.0
Prismaでデータベースを使ったテストをするまでの流れ
Prismaでデータベースを使ったテストを導入するまでの流れは以下の通りです。
- スキーマと実装およびテストファイルを用意
- Dockerでテスト用のDBを用意する
- .env.testを作成する
- コンテナを立ち上げる
- dotenv-cliをインストールする
- package.jsonにコマンドを追加する
- マイグレーションを実行する
- テストを実行する
0. 前提について(プロジェクトの現状)
本題に入る前に、まずは前提を共有しておきます。
今は、以下のコマンドを使ってNext.jsのプロジェクトを作成した状況です。(with-jest-appの部分には任意のアプリ名を指定可能)
npx create-next-app@latest --example with-jest with-jest-app
参考:Jest and React Testing Library
Jest(JavaScriptのテスティングフレームワーク)を使って以下のコマンドでテストを実行できる状態になっています。
npm run test:ci
また、こちらの記事を参考に以下のコマンドを実行することで、Prismaのインストールも完了しています。
npm install prisma --save-dev
npm install @prisma/client
npx prisma init
さらに、schema.prismaの中のproviderを、今回使用するDBであるMySQLに変更しています。
// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") }
以上がプロジェクトの現状です。
1. スキーマと実装およびテストファイルを用意
準備が整ったところで、テーブルのスキーマファイル(schema.prisma)と実装およびテストファイルを用意していきます。
※この項目については、既にスキーマの定義や実装が終わっている方は飛ばしても大丈夫です
まずは、shcema.prismaを以下のように変更します。
generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) name String? @db.VarChar(255) }
User情報を扱うためのUserモデルを作成しました。
shcema.prismaを変更したので、以下のコマンドでPrisma Clientに変更を反映させます。
npx prisma generate
そして、以下のファイルをそれぞれ作成し、中にデータベースを使った処理の実装とテストを追加します。
- components/sample/index.ts
- components/sample/index.spec.ts
components/sample/index.ts
import { PrismaClient } from ".prisma/client" const createUser = async (id: number, name: string) => { const prisma = new PrismaClient(); await prisma.user.create({ data: { id: id, name: name, }, }) } export default createUser;
components/sample/index.spec.ts
import { PrismaClient } from ".prisma/client"; import createUser from "." afterAll(async () => { const prisma = new PrismaClient(); await prisma.$transaction([ prisma.user.deleteMany(), ]) }) test('指定したIDと名前のユーザーを作成できる', async () => { await createUser(1, 'Web系エンジニアのhee'); const prisma = new PrismaClient; const createdUser = prisma.user.findFirst(); expect(await createdUser).toEqual({ id: 1, name: 'Web系エンジニアのhee', }) })
シンプルなユーザー作成の処理とそのテストです。
2. Dockerでテスト用のDBを用意する
テストを実行するために必要なDBを用意します。
プロジェクトルートに、以下のdocker-compose.yamlを作成します。
version: '3.9' services: db: image: mysql:8.0 ports: - '3306:3306' volumes: - ./docker/db:/docker-entrypoint-initdb.d environment: MYSQL_ROOT_PASSWORD: root MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_DATABASE: test
さらに、docker/db配下に以下のファイルも追加します。
privileges.sql
grant create, alter, drop, references on *.* to user;
これは、使用するMySQLのuserに特定の権限を付与するための設定です。
Prismaでは、マイグレーションの際に、shadow databaseと呼ばれる一時的なデータベースが作成されます。
このとき、(MySQLの場合)userに対して以下の4つの権限が必要になります。
- CREATE
- ALTER
- DROP
- REFERENCES
この設定をしていなかったら、マイグレーションの際に以下のようなエラーになるので注意しましょう。
Prisma Migrate could not create the shadow database. Please make sure the database user has permission to create database.
3. .env.testを作成する
プロジェクトルートに、テスト用のDB接続情報を定義するための.env.testを作成します。
DATABASE_URL="mysql://user:password@127.0.0.1:3306/test"
URL内に先ほどdocker-compose.yamlで作成したDBの接続情報を埋め込みます。
4. コンテナを立ち上げる
以下のコマンドを実行して、テスト用DBのDockerコンテナを立ち上げます。
docker-compose up -d
docker-compose ps
でStateがUpになっていたらOKです。
5. dotenv-cliをインストールする
以下のコマンドでdotenv-cliをインストールします。
npm install -g dotenv-cli
これにより、場面に応じて読み込む.envを切り替えることができるようになります。
6. package.jsonにコマンドを追加する
次に、マイグレーション(テーブルの作成)とテストの実行を行うための以下のコマンドを、package.jsonのscriptsに追加します。
"test": "dotenv -e .env.test jest", "migrate:test": "dotenv -e .env.test -- npx prisma migrate dev"
これにより、npm run test
とnpm run migrate:test
でそれぞれテストの実行とテスト用テーブルの作成(マイグレーション)ができるようになりました。
7. マイグレーションを実行する
先ほど設定したコマンドを使ってマイグレーションを実行します。
npm run migrate:test
これにより、schema.prismaに定義したUserモデルを基にusersテーブルがテスト用DBに作成されます。
8. テストを実行する
以下のコマンドでデータベースを使ったテストを実行します。
npm run test
テストが通っていることを確認できました。
以上がPrismaでデータベースを使ったテストをするまでの流れです。
Prismaでデータベースを使ったテストをするまでの流れ まとめ
Prismaでデータベースを使ったテストは以下の流れで実行できます。
- スキーマと実装およびテストファイルを用意
- Dockerでテスト用のDBを用意する
- .env.testを作成する
- コンテナを立ち上げる
- dotenv-cliをインストールする
- package.jsonにコマンドを追加する
- マイグレーションを実行する
- テストを実行する
この記事がPrismaを使った開発を進めていく上で少しでも参考になっていれば幸いです。
最後まで読んでいただきありがとうございました!
Prisma:参考資料
- Prisma:Integration testing
- Prisma:Using multiple .env files
- Prismaのマイグレーションで詰まった作業ログ
- MySQLでprisma migrate devが失敗する