Next.js14で単体テストをJestからVitestに移行したときのメモ

2024-04-23T09:27:35.279Z

はじめに

Jestのバージョンを上げたらESModules, CommonJS問題で苦労したのでバージョンを戻して開発を進めていたがいろいろ問題があったのでVitestに移行した。

弊プロジェクトでやったことのメモなので細かいところは公式のドキュメントやガイドを参照してね。

作業

必要packageのインストール

公式手順

yarn add -D vitest @vitejs/plugin-react jsdom @testing-library/react

追加で入れたpackage

  • vitest-mock-extended
    • jest-mock-extendedと置き換える
  • vitest-tsconfig-paths
    • path aliasをtsconfigから取得して設定してくれるプラグイン
  • happy-dom
    • パフォーマンスが良いみたいなのを見たのでjs-domから置き換え
yarm add -D vitest-mock-extended vitest-tsconfig-paths happy-dom

設定ファイル追加

vitest.config.ts

import react from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'
import { defineConfig } from 'vitest/config'

export default defineConfig({
  define: {
    'import.meta.vitest': false,
  },
  plugins: [
    react(),
    tsconfigPaths(),
    stubNextAssetImport(),
  ],
  test: {
    globals: true,
    environment: 'happy-dom',
    setupFiles: [
      './.tests/vitest.setup.js',
      './.tests/prisma.ts',
    ],
  },
})

// Nestjsの画像インポートの仕様に合わせてstub作成するプラグインを作成する
function stubNextAssetImport() {
  return {
    name: 'stub-next-asset-import',
    transform(_code: string, id: string) {
      if (/(jpg|jpeg|png|webp|gif|svg)$/.test(id)) {
        return {
          code: `export default { src: '${id}', height: 1, width: 1 }`,
        }
      }
    },
  }
}

tests/vitest.setup.js

jest.setup.js を複製して作成しているからなんかおかしいかも。

// Optional: configure or set up a testing framework before each test.
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`

// Used for __tests__/testing-library.js
// Learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom";
import { loadEnvConfig } from "@next/env";

// if (typeof global.TextEncoder === "undefined") {
//   global.TextEncoder = require("util").TextEncoder;
// }

// if (typeof global.TextDecoder === "undefined") {
//   global.TextDecoder = require("util").TextDecoder;
// }

// 以下を追記、.envから環境変数を読ませる処理を書く必要があった
loadEnvConfig(process.cwd());

TextEncoder, TextDecoder はJest時代に用意したやつだけど消して動くか確かめていない。
消してOKだった。

公式のMigration Guideをみながらコード修正

https://vitest.dev/guide/migration.html

  • jest.mock()などをvi.mock()などに置き換え
    • jest. → vi.
    • jest.requireActual() → await vi.importActual()
    • type jest.MockedFunction → type MockedFunction
  • 弊プロジェクトではこれだけで終わった

npm scripts の修正

vitestで起動すると環境を見て自動でwatchかrunを切り替えてくれるらしいがCIで使う用のtest:ciにはrunを指定しておく。

-   "test": "jest",
+   "test": "vitest",
-   "test:ci": "jest --ci",
+   "test:ci": "vitest run",

Miyulab