Jest
, React Testing Library
を用いたテスト時に、next/link
周りで出たエラーの対処法です。
エラー内容
TypeError: Cannot read properties of null (reading 'push')
対処法
対処法はどちらでも問題ないです。
その1:next/linkをモックする
jest.mock('next/link', () => ({
__esModule: true,
default: function Link({
href,
children,
}: {
href: string
children: ReactNode
}) {
return (
<a href={href}>
{children}
</a>
)
},
}))
その2:イベントをキャンセルする
next/link
の中の要素にクリックイベントを付与した場合などに有効です。
クリックイベントを持つ子要素がクリックされたとき、そのイベントが親要素に伝わるのを防ぐことで、next/link
内に存在するpush
(エラーが起きている箇所)を発火させません。
あくまでこの方法は、子要素のクリックイベントのテストが最優先事項になってます。
MyLink.test.ts
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { MyLink } from './MyLink'
const setup = (jsx: JSX.Element) => {
return {
user: userEvent.setup(),
...render(jsx),
}
}
test('calls click handler when clicking', async () => {
const mockedClickHandler = jest.fn().mockImplementation((event) => {
event?.preventDefault()
})
const { user } = setup(
<MyLink
href="/mylink"
onClick={mockedClickHandler}
/>
)
await user.click(screen.getByRole('link'))
expect(mockedClickHandler).toHaveBeenCalledTimes(1)
})
MyLink.ts
イベントをキャンセルするために、クリック時の関数はMouseEventHandler
型を使用する必要があります。
type Props = {
href: string
onClick?: MouseEventHandler<HTMLAnchorElement>
}
export const MyLink = ({ href, onClick }: Props) => {
return (
<Link href={href}>
<a onClick={onClick}>
Click me!
</a>
</Link>
)
}