🐧

next/router をモックして、locale で表示切り替えしているコンポーネントをテストする

2022/09/20に公開

はじめに

Next.js は i18n の機能をサポートしており、この機能を使うことでサイトを多言語表示できます。

https://nextjs.org/docs/advanced-features/i18n-routing

今回は日本語 / 英語で表示を切り替えるコンポーネントを作成して、そのコンポーネントをテストします。

前提

Next.js のプロジェクトを作成し、jest が導入済であることを想定しています。
以下のように locale を取得し、表示を切り替えているコンポーネントをテストします。

Profile.tsx
import { FC } from 'react'
import { useRouter } from 'next/router'
import { en } from '../i18n/en'
import { ja } from '../i18n/ja'

export const Profile: FC = () => {
  const { locale } = useRouter()
  const t = locale === 'en' ? en : ja
  
  return (
    <div>
      <h1>{t.name}</h1>
    </div>
  )
}
en.ts
export const en = {
  name: 'Bob',
}
ja.ts
export const ja = {
  name: 'ボブ',
}
next.config.js
/** @type {import('next').NextConfig} */
module.exports = {
  i18n: {
    locales: ['en', 'ja'],
    defaultLocale: 'ja'
  }
}

また以下の環境で動作確認しています。

"next": "^12.3.0",
"react": "18.2.0",
"@testing-library/react": "^13.4.0",
"jest": "^29.0.3",
"typescript": "4.8.3"

テストする

以下のように next/router をモックしテストを行います。

ProfileJa.test.tsx
import React from 'react'
import { render, screen } from '@testing-library/react'
import { Profile } from '../components/Profile'

jest.mock('next/router', () => ({
  useRouter() {
    return {
      locale: 'ja',
    }
  },
}))

describe('日本語での表示テスト', () => {
  test('名前が表示されているか', () => {
    render(<Profile />)
    expect(screen.getByRole('heading')).toHaveTextContent('ボブ')
  })
})

英語での表示をテストしたいときは以下のように、locale: 'en' にすることでテストを行えるようになります。

ProfileEn.test.tsx
import React from 'react'
import { render, screen } from '@testing-library/react'
import { Profile } from '../components/Profile'

jest.mock('next/router', () => ({
  useRouter() {
    return {
      locale: 'en',
    }
  },
}))

describe('英語での表示テスト', () => {
  test('名前が表示されているか', () => {
    render(<Profile />)
    expect(screen.getByRole('heading')).toHaveTextContent('Bob')
  })
})
GitHubで編集を提案

Discussion