⚡
vitest+reactでreact-error-boundryによってフォールバック画面が表示されるかテストする
はじめに
bulletproof-reactに従ってwebアプリを作ったのですが、vitestでエラーフォールバック画面のテストを書くのに死ぬほど苦労したので後続の方のために記事を残します
ためになったらハート下さい(乞食)
テスト対象コンポーネント
App.tsx
import {AppProvider} from "@/providers/app.tsx"
import {ArticleList} from "@/features/article"
const App = () => {
return (
<AppProvider>
{/* 省略 */}
<ArticleList/>
{/* 省略 */}
</AppProvider>
)
}
export default App
エラーハンドリング
テスト対象のAppはAppProviderでエラーハンドリングしています
app.tsx
export const AppProvider: FC<Props> = (props) => {
return (
<ErrorBoundary FallbackComponent={<div>Something went wrong.</div>}>
{props.children}
</ErrorBoundary>
)
}
テスト実装
App.test.tsx
import App from "./App"
import {ArticleList} from "@/features/article"
import {render, screen} from "@testing-library/react"
vi.mock("@/features/article", async () => {
const actual = await vi.importActual("@/features/article") as object
return {
...actual,
ArticleList: vi.fn(() => <AritcleList/>)
}
})
const mockedArticleList = ArticleList as jest.Mock
describe("App", () => {
beforeEach(() => {
vi.resetAllMocks()
})
test("エラー発生時フォールバック画面を表示する", () => {
mockedArticleList.mockImplementation(() => {throw new Error("test error")})
render(<App/>)
expect(screen.getByText("Something went wrong.")).toBeInTheDocument()
})
解説
"@/features/article"というパスでimportされるすべての関数をモックしています
ただし、ArticleList以外は実際の関数を返しています
ArticleListは実行されるとデフォルトでは本来のコンポーネントを返すモック関数になっています
vi.mock("@/features/article", async () => {
const actual = await vi.importActual("@/features/article") as object
return {
...actual,
ArticleList: vi.fn(() => <AritcleList/>)
}
})
このテストに限りArticleListをレンダリングしようとするとエラーが発生するようにします
mockedArticleList.mockImplementation(() => {throw new Error("test error")})
こうすることで他のテストではArticleListの状態を気にする必要がなくなります
結果
成功!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
最後に
jestの古臭すぎる所が嫌でvitestを使ってみたのですが、新しすぎるが故にChatGPTが使い物にならなかったりして死ぬほどめちゃくちゃ大変でした
皆でvitestを盛り上げよう!!!!!!!!!!!!!!!!!!!!!!!!
Discussion