Composable、ストア、APIのモック
vi.mock()、useFetchのモック、Piniaストアのモック、テストでのルーターのモック
「Composable、ストア、APIのモック」はCoddyKit上の無料Vue Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはVue Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Vue Academyコースには全4レッスンが含まれています。
モックを使う理由
単体テストでは、テスト対象のコンポーネントを分離すべきです。実際のネットワーク呼び出し、実際のストア、負荷の大きい composable は、テストを遅く不安定にします。モックを使うと、こうした依存関係を制御可能な偽物に置き換えられます。
vi.fn: モック関数
vi.fn()は、呼び出しを追跡できる関数を作成します。どのように呼び出されたかを調べたり、戻り値を制御したりできます。これは、あらゆるモックの基本要素です。
import { vi } from "vitest"
const onSave = vi.fn()
onSave("draft")
expect(onSave).toHaveBeenCalledWith("draft")
expect(onSave).toHaveBeenCalledTimes(1)戻り値の設定
同期処理ではmockReturnValue、非同期処理では解決済みのPromiseを返すmockResolvedValueを使って、モックの出力を制御します。
const getId = vi.fn().mockReturnValue(42)
expect(getId()).toBe(42)
const fetchUser = vi.fn().mockResolvedValue({ name: "Ada" })
// await fetchUser() => { name: "Ada" }Composableモジュールのモック
vi.mock(path)はモジュール全体を置き換えます。偽のエクスポートを返すファクトリを指定します。composableをスタブ化し、コンポーネントが予測可能なデータを受け取るようにする場合に使います。
import { vi } from "vitest"
vi.mock("@/composables/useUser", () => ({
useUser: () => ({
user: { value: { name: "Ada" } },
isLoading: { value: false },
}),
}))vi.mockのホイスティング
vi.mockの呼び出しは、importが実行される前にファイルの先頭へホイスティングされます。そのため、ファクトリから後で定義される外側の変数を参照することはできません。ヘルパーはファクトリ内、またはvi.hoistedを使って宣言してください。
// This runs before imports regardless of position.
vi.mock("@/api", () => ({ getPosts: vi.fn() }))
import { getPosts } from "@/api" // already the mockPiniaストアのテスト
Piniaストアを使うコンポーネントには、テストでもストアが必要です。@pinia/testingはcreateTestingPiniaを提供し、アクションがデフォルトでモック化されたストアを作成できます。
// terminal: npm install -D @pinia/testing
import { createTestingPinia } from "@pinia/testing"テスト用Piniaの導入
マウント時に、テスト用Piniaをglobalのpluginsオプションに渡します。初期状態を設定することもできます。
import { mount } from "@vue/test-utils"
import { createTestingPinia } from "@pinia/testing"
const wrapper = mount(Profile, {
global: {
plugins: [createTestingPinia({
initialState: { user: { name: "Ada" } },
})],
},
})ストアのアクションをアサートする
デフォルトでは、アクションはスタブ化されて実行されないため、ディスパッチされたことをアサートできます。ストアを取得し、スパイを確認してください。
import { useUserStore } from "@/stores/user"
const store = useUserStore()
await wrapper.get("button.logout").trigger("click")
expect(store.logout).toHaveBeenCalled()fetchをスパイする
モジュール全体を置き換える代わりに、グローバルをスパイすることもできます。vi.spyOn(global, "fetch")は実際のfetchをラップするため、動作を上書きしたり呼び出しを調べたりできます。
const spy = vi.spyOn(global, "fetch").mockResolvedValue({
ok: true,
json: async () => ({ items: [1, 2, 3] }),
})fetchの完全なテスト
fetchをモックし、アクションを実行してPromiseをフラッシュします。その後、レンダリングされたデータと、正しいURLでfetchが呼び出されたことをアサートします。
it("loads items", async () => {
vi.spyOn(global, "fetch").mockResolvedValue({
ok: true,
json: async () => ({ items: ["a", "b"] }),
})
const wrapper = mount(List)
await flushPromises()
expect(global.fetch).toHaveBeenCalledWith("/api/items")
expect(wrapper.findAll("li")).toHaveLength(2)
})テスト間でモックをリセットする
共有モックには呼び出し履歴が蓄積されます。beforeEachでリセットするか、設定でclearMocksを有効にして、あるテストの影響が別のテストに漏れないようにしてください。
import { beforeEach, vi } from "vitest"
beforeEach(() => {
vi.clearAllMocks()
})理解度チェック
モックについての理解度を確認しましょう。
復習
テストで依存関係をモックする方法を学びました。
vi.fn()は呼び出しを追跡できる関数を作成します。mockReturnValue/mockResolvedValueで出力を制御できます。vi.mock(path, factory)はモジュール(composableなど)を置き換えます。importより前にホイスティングされます。@pinia/testingのcreateTestingPiniaは、アサート可能なスタブ化されたアクションを持つストアを提供します。vi.spyOn(global, "fetch").mockResolvedValue(...)でネットワーク呼び出しを偽装できます。vi.clearAllMocks()を使って、テスト間でモックをリセットします。
よくある質問
「Composable、ストア、APIのモック」レッスンは無料ですか?
はい。「Composable、ストア、APIのモック」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Vue Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Vue Academyコースには全4レッスンが含まれています。
「Composable、ストア、APIのモック」で何を学びますか?
vi.mock()、useFetchのモック、Piniaストアのモック、テストでのルーターのモック ブラウザで直接実行するハンズオンコードでVue Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Vue Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのVue Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「Composable、ストア、APIのモック」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このVue Academyレッスンでコードを書いて実行できますか?
はい。すべてのVue Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- VueプロジェクトでのVitest設定
- コンポーネントのマウントと検索
- ユーザー操作とイベントのテスト
- Composable、ストア、APIのモック