vue-test-utils
提供了一種 mock 掉 Vue.prototype
的簡單方式,不但對測試用例適用,也能夠爲全部測試設置默認的 mock。javascript
mocks
加載選項 是一種將任何屬性附加到 Vue.prototype
上的方式。這一般包括:html
$store
, for Vuexvue
$router
, for Vue Routerjava
$t
, for vue-i18nbash
以及其餘種種。app
咱們來看一個 vue-i18n 的例子。雖然能夠爲每一個測試用到 createLocalVue
並安裝 vue-i18n
,但那樣可能會讓事情難以處理並引入一堆樣板。首先,組件 <Bilingual>
用到了 vue-i18n
:函數
<template>
<div class="hello">
{{ $t("helloWorld") }}
</div>
</template>
<script>
export default {
name: "Bilingual"
}
</script>複製代碼
你先在另外一個文件中弄好翻譯,而後經過 $t
引用,這就是 vue-i18n
的工做方式。在本次測試中,雖然並不會真正關心翻譯文件看起來什麼樣,不過仍是看一看此次用到的:單元測試
export default {
"en": {
helloWorld: "Hello world!"
},
"ja": {
helloWorld: "こんにちは、世界!"
}
}複製代碼
基於這個 locale,正確的翻譯將被渲染出來。咱們先不用 mock,嘗試在測試中渲染該組件:測試
import { shallowMount } from "@vue/test-utils"
import Bilingual from "@/components/Bilingual.vue"
describe("Bilingual", () => {
it("renders successfully", () => {
const wrapper = shallowMount(Bilingual)
})
})複製代碼
經過 yarn test:unit
運行測試將拋出一堆錯誤堆棧。若仔細端詳輸出則會發現:ui
[Vue warn]: Error in config.errorHandler: "TypeError: _vm.$t is not a function"複製代碼
這是由於咱們並未安裝 vue-i18n
,因此全局的 $t
方法並不存在。咱們試試 mocks
加載選項:
import { shallowMount } from "@vue/test-utils"
import Bilingual from "@/components/Bilingual.vue"
describe("Bilingual", () => {
it("renders successfully", () => {
const wrapper = shallowMount(Bilingual, {
mocks: {
$t: (msg) => msg
}
})
})
})複製代碼
如今測試經過了! mocks
選項用處多多,而我以爲最最經常使用的正是開頭提到過的那三樣。
(譯註:經過這種方式就不能在單元測試中耦合與特定語言相關的內容了,由於翻譯功能實際上已失效,也更沒法處理可選參數等)
有時須要一個 mock 的默認值,這樣就不用爲每一個測試用例都設置一遍了。能夠用 vue-test-utils
提供的 config API 來實現。仍是 vue-i18n
的例子:
import VueTestUtils from "@vue/test-utils"
VueTestUtils.config.mocks["mock"] = "Default Mock Value"複製代碼
這個示例中用到了 Jest,因此我將把默認 mock 描述在 jest.init.js
文件中 -- 該文件會在測試運行前被自動加載。同時我也會導入並應用此前用於示例的翻譯對象。
//jest.init.js
import VueTestUtils from "@vue/test-utils"
import translations from "./src/translations.js"
const locale = "en"
VueTestUtils.config.mocks["$t"] = (msg) => translations[locale][msg]複製代碼
如今儘管仍是用了一個 mock 過的 $t
函數,但會渲染一個真實的翻譯了。再次運行測試,此次移除了 mocks
加載選項並用 console.log
打印了 wrapper.html()
。
describe("Bilingual", () => {
it("renders successfully", () => {
const wrapper = shallowMount(Bilingual)
console.log(wrapper.html())
})
})複製代碼
測試經過,如下結構被渲染出來:
<div class="hello">
Hello world!
</div>複製代碼
(譯註:依然沒法應付複雜的翻譯)
本文論述了:
在測試用例中使用 mocks
以 mock 一個全局對象
用 config.mocks
設置默認的 mock