Next.js×TypeScript環境でJest→Vitestに移行してみた
はじめに
普通に新たな Vite プロジェクトを作って、Vitest を始める場合は先日公開したこちらの記事をご覧ください。
リンク入れるリンク入れるリンク入れるリンク入れるリンク入れるリンク入れる
今回はタイトルにもあるように、移行がテーマです。
以前自分が作成した Next.js×TypeScript のプロジェクトで Jest を使っており、それを Vitest へ移行する対応を行なった時のまとめがこの記事の内容です。
実際の対応内容はこちらのプルリクをご覧いただければよく分かるかと思います。
やったこと
だいたいこんな感じです。
- Vitest のインストール
-
vitest.config.ts
を用意する -
npx vitest run
して出てきたエラーを潰す
では詳しく書きます。
Vitest のインストール
npm install するだけ。
npm install -D vitest
あと、Vitest の実行のために vite の React プラグインが必要ですので、インストールしておきます。
npm install -D @vitejs/plugin-react
vitest.config.ts
を用意する
vitest の設定のためにvitest.config.ts
を用意して、設定を書いていきます。
このあとのエラーを解消するためにいろいろ書き足した最終系を載せておきます。
/// <reference types="vitest" />
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vitest/config'
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: './src/test/setup.ts',
},
resolve: {
alias: {
'@': __dirname + '/src',
},
},
})
初期状態は Vitest がサンプルを公開してくれているので、そちらを見るとよいでしょう。
src/test/setup.ts を作る
これは必須対応というわけではないのですが、全てのテストファイルに@testing-library/jest-dom
の import 文を書く手間を省くために入れたという感じです。
その他必要な前処理があれば、setup.ts
に書くという感じです。
今回は import 文だけです。
import '@testing-library/jest-dom'
npx vitest run
して出てきたエラーを潰す
まずは実行前に、全てのテストコードにvitest
の import を書き足します。
test
やdescribe
、expect
は Jest のものなので、この辺りを import してあげる必要があります。
import { expect, test, describe } from 'vitest'
これだけ入れたら、一旦npx vitest run
してみます。すると案の定エラーが出ます。
出てきたエラー
ざっとこんなな感じです。
FAIL src/Components/__test__/header.test.jsx [ src/Components/__test__/header.test.jsx ]
ReferenceError: describe is not defined
❯ src/Components/__test__/header.test.jsx:5:1
3| import Header from '../header'
4|
5| describe('Header部分のテスト', () => {
| ^
6| test('boobyというタイトル文字が表示されているかどうか', () => {
7| const { getByText } = render(<Header />)
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/5]⎯
FAIL src/Components/__test__/pagination.test.tsx [ src/Components/__test__/pagination.test.tsx ]
ReferenceError: jest is not defined
❯ src/Components/__test__/pagination.test.tsx:5:1
3| import Pagination from '../pagination'
4|
5| jest.mock('next/router', () => ({
| ^
6| useRouter: jest.fn().mockReturnValue({
7| pathname: '/',
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/5]⎯
FAIL src/Components/__test__/repositoryCard.test.jsx [ src/Components/__test__/repositoryCard.test.jsx ]
Error: Failed to load url @/Components/repositoryCard (resolved id: @/Components/repositoryCard) in /rootpath/src/Components/__test__/repositoryCard.test.jsx. Does the file exist?
❯ loadAndTransform node_modules/vite/dist/node/chunks/dep-8609dc5d.js:54816:21
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/5]⎯
FAIL src/Components/__test__/repositorySearchForm.test.jsx [ src/Components/__test__/repositorySearchForm.test.jsx ]
Error: Failed to load url @/Components/repositorySearchForm (resolved id: @/Components/repositorySearchForm) in /rootpath/src/Components/__test__/repositorySearchForm.test.jsx. Does the file exist?
❯ loadAndTransform node_modules/vite/dist/node/chunks/dep-8609dc5d.js:54816:21
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/5]⎯
FAIL src/Components/__test__/select.test.jsx [ src/Components/__test__/select.test.jsx ]
Error: Failed to load url @/Components/select (resolved id: @/Components/select) in /rootpath/src/Components/__test__/select.test.jsx. Does the file exist?
❯ loadAndTransform node_modules/vite/dist/node/chunks/dep-8609dc5d.js:54816:21
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/5]⎯
Test Files 5 failed (5)
Tests no tests
Start at 07:57:15
Duration 903ms (transform 230ms, setup 0ms, collect 0ms, tests 0ms, environment 805ms, prepare 180ms)
分類するとこんな感じです。
- ReferenceError
- describe is not defined
- jest is not defined
- Error: Failed to load url
対処法を書いていきます。
ReferenceError
これは単純に Jest から Vitest に置き換えたことで存在しない export を呼んでいることによるエラーです。
describe は単に先に書いた import 漏れなのですが、もう一つは Jest の mock を使っていることによるエラーでした。
jest.mock('next/router', () => ({
useRouter: jest.fn().mockReturnValue({
pathname: '/',
query: { language: 'javascript' },
}),
では、Jest の mock を Vitest の mock へ置き換える必要がありますが、どうしたかというとこうしました。
vi.mock('next/router', () => ({
useRouter: vi.fn().mockReturnValue({
pathname: '/',
query: { language: 'javascript' },
}),
はい、単にjest
からvi
に置き換えただけです。
一応後日また Vitest の mock をいろいろ試した記事を公開する予定です。
Error: Failed to load url
これは import で@/Components/select
のようにパスエイリアスを使っていることが問題になってました。
要は、Vitest は@
がどこのパスを指しているのか、そのままだと解釈できていないということです。
なのでvitest.config.ts
のdefineConfig
に以下の設定を追加する必要がありました。
resolve: {
alias: {
'@': __dirname + '/src',
},
},
これで vitest は@/Components/select
をうまく認識してくれるようになりました。
おわりに:対応してみた感想
意外と簡単に対応できました。
Vitest 公式に Jest からの移行のドキュメントがあるくらいなので、だいぶ意識して作ってるっぽいです。
ただ、mock とか snapshot がいっぱいあるときにどうなるまでは見切れてはない感じなので、それ次第でもしかすると難易度は多少変わってくるのかもしれません。
メンバー募集!
サーバーサイド Kotlin コミュニティを作りました!
Kotlin ユーザーはぜひご参加ください!!
また関西在住のソフトウェア開発者を中心に、関西エンジニアコミュニティを一緒に盛り上げてくださる方を募集しています。
よろしければ Conpass からメンバー登録よろしくお願いいたします。
Discussion