Breathnote
Jestを用いたNext.jsのテストで環境変数を利用する

Jestを用いたNext.jsのテストで環境変数を利用する

Next.jsは、Create React Appのように標準のテスト環境を提供していないため、開発者自身がテスト環境を用意する必要があります。

私は、JestとReact Testing Libraryを使ってこのブログをテストしていますが、環境変数を利用しているコンポーネントをテストする際に、Jestが環境変数をうまく読み込んでくれませんでした。

調べてみると、いくつか対処法が見つかったので、採用した方法とその他諸々をアウトプットしておきます。

最善策

setupEnv.ts
import { loadEnvConfig } from '@next/env'

export default async (): Promise<void> => {
  loadEnvConfig(process.env.PWD || process.cwd())
}
jest.config.js
module.exports = {
  globalSetup: '<rootDir>/setupEnv.ts',
}

テスト実行前に@next/envloadEnvConfig()で環境変数ファイルを読み込みます。

loadEnvConfig()の引数はprocess.env.PWDだけでも動きますが、Windows環境ではprocess.env.PWDundefinedを返す可能性があるため、process.cwd()も追加しています。

他の対処法

上記の方法が最善ですが、残りの対処法も紹介しておきます。

1. Next.jsのインスタンスを生成する

jest.setup.ts
import next from 'next'
next({})
jest.config.js
module.exports = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}

テストの前にNext.jsをインスタンス化してしまい、Next.js環境下でテストを実施する方法です。

この方法の良いところは、環境変数だけでなくfetch関数なども利用可能になる点でしょう。

ただ、インスタンスの作成にはビルドした.nextフォルダが必要となります。GitHub Actionsなどを用いてテストをCIで回す場合、毎回next buildが必要になります。

あと単純にテストが重くなります。

2. テスト用にdotenvを別途導入する

shell
yarn add --dev dotenv
jest.setup.ts
import dotenv from "dotenv";
dotenv.config({ path: ".env.local" });
jest.config.js
module.exports = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}

上で述べた欠点を改良した原始的な対処法です。

ただ、せっかくNext.jsがビルトインサポートしているdotenvを、テストのためだけに再インストールするのは気が乗りませんでした。