可以在 <App> 测试中使用一个相同的 localVue,并将其声明在第一个 describe 块之外。而由于要为不同的路由做不同的测试,所以把 router 定义在 it 块里。
另一个要注意的是这里用了 mount 而非 shallowMount。如果用了 shallowMount,则 <router-link> 就会被忽略,不管当前路由是什么,渲染的其实都是一个无用的替身组件。
为使用了 mount 的大型渲染树做些变通
使用 mount 在某些情况下很好,但有时却是不理想的。比如,当渲染整个 <App> 组件时,正赶上渲染树很大,包含了许多组件,一层层的组件又有自己的子组件。这么些个子组件都要触发各种生命周期钩子、发起 API 请求什么的。
如果你在用 Jest,其强大的 mock 系统为此提供了一个优雅的解决方法。可以简单的 mock 掉子组件,在本例中也就是 <NestedRoute>。使用了下面的写法后,以上测试也将能通过:
jest.mock("@/components/NestedRoute.vue", () => ({
name: "NestedRoute",
render: h => h("div")
}))
使用 Mock Router
有时真实路由也不是必要的。现在升级一下 <NestedRoute>,让其根据当前 URL 的查询字符串显示一个用户名。这次我们用 TDD 实现这个特性。以下是一个基础测试,简单的渲染了组件并写了一句断言:
import { shallowMount } from "@vue/test-utils"
import NestedRoute from "@/components/NestedRoute.vue"
import routes from "@/routes.js"describe("NestedRoute", () => {
it("renders a username from query string", () => {
const username = "alice"
const wrapper = shallowMount(NestedRoute)
expect(wrapper.find(".username").text()).toBe(username)
})
})
然而我们并没有 <div class=”username”> ,所以一运行测试就会报错:
tests/unit/NestedRoute.spec.js
NestedRoute
✕ renders a username from query string (25ms)● NestedRoute › renders a username from query string
[vue-test-utils]: find did not return .username, cannot call text() on empty Wrapper
来更新一下 <NestedRoute>:
<template>
<div>
Nested Route
<div class="username">
{{ $route.params.username }}
</div>
</div>
</template>
现在报错变为了:
tests/unit/NestedRoute.spec.js
NestedRoute
✕ renders a username from query string (17ms)● NestedRoute › renders a username from query string










