对 Vue-Router 进行单元测试的方法

2020-06-14 06:17:49易采站长站整理


//router.js

export function beforeEach((to, from, next) {
if (to.matched.some(record => record.meta.shouldBustCache)) {
bustCache()
}
next()
}

router.beforeEach((to, from, next) => beforeEach(to, from, next))

export default router

再写测试就容易了,虽然写起来有点长:


import { beforeEach } from "@/router.js"
import mockModule from "@/bust-cache.js"

jest.mock("@/bust-cache.js", () => ({ bustCache: jest.fn() }))

describe("beforeEach", () => {
afterEach(() => {
mockModule.bustCache.mockClear()
})

it("busts the cache when going to /user", () => {
const to = {
matched: [{ meta: { shouldBustCache: true } }] }
const next = jest.fn()

beforeEach(to, undefined, next)

expect(mockModule.bustCache).toHaveBeenCalled()
expect(next).toHaveBeenCalled()
})

it("busts the cache when going to /user", () => {
const to = {
matched: [{ meta: { shouldBustCache: false } }] }
const next = jest.fn()

beforeEach(to, undefined, next)

expect(mockModule.bustCache).not.toHaveBeenCalled()
expect(next).toHaveBeenCalled()
})
})

最主要的有趣之处在于,我们借助 jest.mock,mock 掉了整个模块,并用 afterEach  钩子将其复原。通过将 beforeEach  导出为一个已结耦的、普通的 Javascript 函数,从而让其在测试中不成问题。

为了确定 hook 真的调用了 bustCache  并且显示了最新的数据,可以使用一个诸如 Cypress.io 的端到端测试工具,它也在应用脚手架 vue-cli  的选项中提供了。

组件 guards

一旦将组件 guards 视为已结耦的、普通的 Javascript 函数,则它们也是易于测试的。假设我们为 <NestedRoute>  添加了一个 beforeRouteLeave  hook:


//NestedRoute.vue

<script>
import { bustCache } from "@/bust-cache.js"
export default {
name: "NestedRoute",
beforeRouteLeave(to, from, next) {
bustCache()
next()
}
}
</script>

对在全局 guard 中的方法照猫画虎就可以测试它了:


// ...
import NestedRoute from "@/compoents/NestedRoute.vue"
import mockModule from "@/bust-cache.js"

jest.mock("@/bust-cache.js", () => ({ bustCache: jest.fn() }))

it("calls bustCache and next when leaving the route", () => {
const next = jest.fn()
NestedRoute.beforeRouteLeave(undefined, undefined, next)

expect(mockModule.bustCache).toHaveBeenCalled()
expect(next).toHaveBeenCalled()
})

这样的单元测试行之有效,可以在开发过程中立即得到反馈;但由于路由和导航 hooks 常与各种组件互相影响以达到某些效果,也应该做一些集成测试以确保所有事情如预期般工作。