🐈
Next.jsでテストするときのメモ
テキストがあるかのテスト
it('Should render hello text', () => {
render(<Home />)
expect(screen.getByText('Hello Next.js')).toBeInTheDocument()
})
<Home />の中に'Hello Next.js'のテキストがあればパスする。
page navigationのテスト
<a
data-testid="blog-nav"
className="text-gray-300 hover:bg-gray-700 px-3 py-2 rounded"
>
data-testidでテストしたい場所にidを付与
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import userEvent from '@testing-library/user-event'
import { getPage } from 'next-page-tester'
import { initTestHelpers } from 'next-page-tester'
initTestHelpers()
describe('Navigation by Link', () => {
it('Should route to selected page in navbar', async () => {
const { page } = await getPage({
route: '/index',
})
render(page)
userEvent.click(screen.getByTestId('blog-nav'))
expect(await screen.findByText('blog page')).toBeInTheDocument()
})
})
next-page-testerのinitTestHelpersをimportし、
clickイベントなのでuserEvent.click(先程指定したid)で、
非同期処理なのでawaitとfindByTextを使う。
getStaticPropsとgetStaticPathsのテスト
export const getStaticProps: GetStaticProps = async () => {
const posts = await getAllPostsData()
return {
props: { posts },
}
}
getStaticPropsでgetAllPostsDataを実行しているとして、
テストは、以下になります。
const handlers = [
rest.get('https://jsonplaceholder.typicode.com/posts/', (req, res, ctx) => {
const query = req.url.searchParams
const _limit = query.get('_limit')
if (_limit === '10') {
return res(
// 以下はダミーデータです
ctx.status(200),
ctx.json([
{
userId: 1,
id: 1,
title: 'dummy title 1',
body: 'dummy body 1',
},
{
userId: 2,
id: 2,
title: 'dummy title 2',
body: 'dummy body 2',
},
])
)
}
}),
]
Mock Service Workerでhandlersの中にAPIのレスポンスを定義します。
const server = setupServer(...handlers)
セットアップサーバーを立てます。
beforeAll(() => {
server.listen()
})
beforeAllでモックサーバーを起動します。
afterEach(() => {
server.resetHandlers()
cleanup()
})
afterEachでサーバーのリセットとクリーンアップ。
afterAll(() => {
server.close()
})
afterAllでサーバーを閉じます。
describe(`Blog page`, () => {
it('Should render the list of blogs pre-fetched by getStaticProps', async () => {
// blog-pageを取得する
const { page } = await getPage({
route: '/blog-page',
})
// renderでpageの内容を取得する
render(page)
// ブログページのテキストが取得できるまで待機する
expect(await screen.findByText('blog page')).toBeInTheDocument()
// ダミーデータのレスポンスがDOMに表示されているかを確認する
expect(screen.getByText('dummy title 1')).toBeInTheDocument()
expect(screen.getByText('dummy title 2')).toBeInTheDocument()
})
})
テストはこのようになります。
useSWRのテスト
const server = setupServer(
rest.get(
'https://jsonplaceholder.typicode.com/comments/',
(req, res, ctx) => {
const query = req.url.searchParams
const _limit = query.get('_limit')
if (_limit === '10') {
return res(
ctx.status(200),
ctx.json([
{
postId: 1,
id: 1,
name: 'A',
email: 'dummya@gmail.com',
body: 'test body a',
},
{
postId: 2,
id: 2,
name: 'B',
email: 'dummyb@gmail.com',
body: 'test body b',
},
])
)
}
}
)
)
まず、先程と同じようにAPIのサーバー(getレスポンス)を作る。
it('Should render the value fetched by useSWR ', async () => {
render(
<SWRConfig value={{ dedupingInterval: 0 }}>
<CommentPage />
</SWRConfig>
)
expect(await screen.findByText('1:test body a')).toBeInTheDocument()
expect(screen.getByText('2:test body b')).toBeInTheDocument()
})
200番の場合。
useSWRの機能をテストする場合はSWRConfigで括ってdedupingIntervalを0にセットします。
it('Should render Error text when fetch failed', async () => {
server.use(
rest.get(
'https://jsonplaceholder.typicode.com/comments/',
(req, res, ctx) => {
const query = req.url.searchParams
const _limit = query.get('_limit')
if (_limit === '10') {
return res(ctx.status(400))
}
}
)
)
render(
<SWRConfig value={{ dedupingInterval: 0 }}>
<CommentPage />
</SWRConfig>
)
expect(await screen.findByText('Error!')).toBeInTheDocument()
400番の場合。
モックを変更して、Error!が表示されるかのテスト。
Discussion