使用 Mirage 在 Vue Test Utils 中模擬網路請求

使用您的 Mirage 伺服器,利用 Vue Test Utils 在不同的伺服器情境下測試您的 Vue 應用程式。

這是針對已在其 Vue 應用程式中使用 Vue Test Utils 的人員的快速入門指南。

步驟 1:安裝 Mirage

首先,請確認您已安裝 Mirage

# Using npm
npm install --save-dev miragejs

# Using Yarn
yarn add --dev miragejs

步驟 2:定義您的伺服器

建立一個新的 server.js 檔案並定義您的模擬伺服器。

這是一個基本範例

// src/server.js
import { createServer, Model } from "miragejs"

export function makeServer({ environment = "development" } = {}) {
  let server = createServer({
    environment,

    models: {
      user: Model,
    },

    seeds(server) {
      server.create("user", { name: "Bob" })
      server.create("user", { name: "Alice" })
    },

    routes() {
      this.namespace = "api"

      this.get("/users", (schema) => {
        return schema.users.all()
      })
    },
  })

  return server
}

在 Vue CLI 中,將此檔案放在 src/server.js 中,以便對其進行變更時會觸發重新建置。

步驟 3:建立一個使用 Mirage 的測試檔案

這是我們將要測試的 Vue 元件。

<!-- src/App.vue -->
<template>
  <div v-if="serverError" data-testid="server-error">{{ serverError }}</div>

  <div v-else-if="users.length === 0" data-testid="no-users">No users!</div>

  <div v-else>
    <ul id="users">
      <li
        v-for="user in users"
        v-bind:key="user.id"
        :data-testid="'user-' + user.id"
      >
        {{ user.name }}
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    name: "app",

    data() {
      return {
        users: [],
        serverError: null,
      }
    },

    created() {
      fetch("/api/users")
        .then((res) => res.json())
        .then((json) => {
          if (json.error) {
            this.serverError = json.error
          } else {
            this.users = json.users
          }
        })
    },
  }
</script>

建立一個新的 src/App.spec.js 檔案,匯入您的 makeServer 函式,並使用 beforeEachafterEach 啟動和關閉 Mirage,確保將 test 環境傳遞給 Mirage

// src/App.spec.js
import { mount } from "@vue/test-utils"
import { makeServer } from "./server"
import App from "./App.vue"

let server

beforeEach(() => {
  server = makeServer({ environment: "test" })
})

afterEach(() => {
  server.shutdown()
})

步驟 4:使用您的 Mirage 伺服器撰寫測試

使用您的測試在 Mirage 中加入不同的資料情境,然後針對您的 UI 狀態進行斷言。

test 環境中,Mirage 不會載入其資料庫 seeds,以便伺服器在每次測試執行時都從空白開始。

it("shows the users from our server", async () => {
  server.create("user", { id: 1, name: "Luke" })
  server.create("user", { id: 2, name: "Leia" })

  const wrapper = mount(App)

  // let's wait for our vue component to finish loading data
  // we know it's done when the data-testid enters the dom.
  await waitFor(wrapper, '[data-testid="user-1"]')
  await waitFor(wrapper, '[data-testid="user-2"]')

  expect(wrapper.find('[data-testid="user-1"]').text()).toBe("Luke")
  expect(wrapper.find('[data-testid="user-2"]').text()).toBe("Leia")
})

it("shows a message if there are no users", async () => {
  // Don't create any users

  const wrapper = mount(App)
  await waitFor(wrapper, '[data-testid="no-users"]')

  expect(wrapper.find('[data-testid="no-users"]').text()).toBe("No users!")
})

// This helper method returns a promise that resolves
// once the selector enters the wrapper's dom.
const waitFor = function (wrapper, selector) {
  return new Promise((resolve) => {
    const timer = setInterval(() => {
      const userEl = wrapper.findAll(selector)
      if (userEl.length > 0) {
        clearInterval(timer)
        resolve()
      }
    }, 100)
  })
}

步驟 5:變更您的 Mirage 伺服器以測試不同的伺服器狀態

除了不同的資料情境之外,您還可以利用您的測試重新設定您的 Mirage 伺服器,以測試新的情況。

例如,您可以像這樣測試錯誤狀態

// src/App.spec.js
import { Response } from "miragejs"

it("handles error responses from the server", async () => {
  // Override Mirage's route handler for /users, just for this test
  server.get("/users", () => {
    return new Response(
      500,
      {},
      {
        error: "The database is on vacation.",
      }
    )
  })

  const wrapper = mount(App)

  await waitFor(wrapper, '[data-testid="server-error"]')

  expect(wrapper.find('[data-testid="server-error"]').text()).toBe(
    "The database is on vacation."
  )
})

由於我們使用 beforeEachafterEach 設定 Mirage 的方式,每個測試都會根據您的主要伺服器定義取得一個新的 Mirage 伺服器。您在測試中所做的任何覆寫都將隔離到該測試。