使用 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
函数,并使用 beforeEach
和 afterEach
启动和关闭 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."
)
})
由于我们使用 beforeEach
和 afterEach
设置 Mirage,因此每个测试都将获得一个基于你的主服务器定义的全新的 Mirage 服务器。你在测试中做出的任何覆盖都会被隔离到该测试中。