なるほど 👍
Nuxt.js + TanStack Query + Jest で「APIを呼び出して取得したデータを表示するコンポーネント」をテストするサンプルを紹介します。
ここでは 疑似 API をモック化 し、useQuery が返すデータをテスト対象のコンポーネントに流す例を示します。
- Nuxt 3
- @tanstack/vue-query 使用
- Jest + @vue/test-utils 使用
export async function fetchUsers(): Promise<{ id: number; name: string }[]> {
const res = await fetch("https://example.com/api/users");
if (!res.ok) throw new Error("Failed to fetch");
return res.json();
}<script setup lang="ts">
import { useQuery } from "@tanstack/vue-query";
import { fetchUsers } from "~/composables/useApi";
const { data, isLoading, error } = useQuery({
queryKey: ["users"],
queryFn: fetchUsers,
});
</script>
<template>
<div>
<div v-if="isLoading">Loading...</div>
<div v-else-if="error">Error: {{ error.message }}</div>
<ul v-else>
<li v-for="user in data" :key="user.id">{{ user.name }}</li>
</ul>
</div>
</template>import { mount } from "@vue/test-utils";
import { defineComponent } from "vue";
import { VueQueryPlugin, QueryClient, QueryClientProvider } from "@tanstack/vue-query";
import UserList from "~/components/UserList.vue";
// fetchUsers をモック化
jest.mock("~/composables/useApi", () => ({
fetchUsers: jest.fn(),
}));
import { fetchUsers } from "~/composables/useApi";
// VueQuery 用のラッパー
function mountWithVueQuery(component: any) {
const queryClient = new QueryClient();
return mount(component, {
global: {
plugins: [
[VueQueryPlugin, { queryClient }],
],
},
});
}
describe("UserList.vue", () => {
it("APIデータを表示できる", async () => {
(fetchUsers as jest.Mock).mockResolvedValue([
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
]);
const wrapper = mountWithVueQuery(UserList);
// データ取得完了を待つ
await flushPromises();
expect(wrapper.text()).toContain("Alice");
expect(wrapper.text()).toContain("Bob");
});
it("エラー時の表示", async () => {
(fetchUsers as jest.Mock).mockRejectedValue(new Error("API failed"));
const wrapper = mountWithVueQuery(UserList);
await flushPromises();
expect(wrapper.text()).toContain("Error: API failed");
});
it("ローディング表示", async () => {
(fetchUsers as jest.Mock).mockImplementation(
() => new Promise(() => {}) // resolveしない
);
const wrapper = mountWithVueQuery(UserList);
expect(wrapper.text()).toContain("Loading...");
});
});- Nuxt でも jest で Vue コンポーネントをテストする場合 →
@vue/test-utilsを使う - VueQuery の依存性注入 →
VueQueryPluginをglobal.pluginsに渡す - API は jest.mock でモック化
- 非同期処理の完了を待つ →
await flushPromises()を使う
👉 このサンプルを Nuxt プロジェクトに組み込めば、
- API が成功するケース
- 失敗するケース
- ローディング中
の3パターンをテストできます。
ご希望に合わせて、このサンプルを Nuxt の pages/index.vue を対象にしたテスト例 に書き換えることもできますが、そちらにしますか?
いい質問です 👍 基本的な流れは Jest → Vitest に差し替え で動きますが、いくつかポイントがあります。
jest.mock→vi.mockjest.fn→vi.fn- 非同期処理待ち →
flushPromisesはそのまま使えます - 実行コマンドは
vitest(Nuxt3 ならnuxi testでもOK)
import { mount, flushPromises } from "@vue/test-utils";
import { describe, it, expect, vi } from "vitest";
import { VueQueryPlugin, QueryClient } from "@tanstack/vue-query";
import UserList from "~/components/UserList.vue";
// fetchUsers をモック化
vi.mock("~/composables/useApi", () => ({
fetchUsers: vi.fn(),
}));
import { fetchUsers } from "~/composables/useApi";
// VueQuery 用のラッパー
function mountWithVueQuery(component: any) {
const queryClient = new QueryClient();
return mount(component, {
global: {
plugins: [[VueQueryPlugin, { queryClient }]],
},
});
}
describe("UserList.vue (vitest)", () => {
it("APIデータを表示できる", async () => {
(fetchUsers as unknown as ReturnType<typeof vi.fn>).mockResolvedValue([
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
]);
const wrapper = mountWithVueQuery(UserList);
await flushPromises();
expect(wrapper.text()).toContain("Alice");
expect(wrapper.text()).toContain("Bob");
});
it("エラー時の表示", async () => {
(fetchUsers as unknown as ReturnType<typeof vi.fn>).mockRejectedValue(
new Error("API failed")
);
const wrapper = mountWithVueQuery(UserList);
await flushPromises();
expect(wrapper.text()).toContain("Error: API failed");
});
it("ローディング表示", async () => {
(fetchUsers as unknown as ReturnType<typeof vi.fn>).mockImplementation(
() => new Promise(() => {}) // resolveしない
);
const wrapper = mountWithVueQuery(UserList);
expect(wrapper.text()).toContain("Loading...");
});
});vi.mockの場合は import の前にモック宣言してもOK ですが、上記のようにvi.mock→importの順に書けば Jest と同じ流れで書けます。- Nuxt 3 + Vitest の場合、デフォルトで
@vue/test-utilsが動作するようになっているので、特別な設定は不要です。
👉 Jest 版からの変更点は jest → vi の置き換え だけで、テストの流れは全く同じです。
ご希望なら、このサンプルを Nuxt3 の nuxi test 環境(nuxt.config.ts 設定込み)に合わせた完全セットアップ例 も提示できますが、そこまで要りますか?