使用 vue-testing-library 测试 vue 观察者
Posted
技术标签:
【中文标题】使用 vue-testing-library 测试 vue 观察者【英文标题】:Testing vue watchers with vue-testing-library 【发布时间】:2021-08-12 22:04:17 【问题描述】:有人知道我将如何使用 vue-testing-library 在组件中测试观察者吗?
这是我的组件。我想测试更新品牌vuex状态时是否调用了该方法。使用 vue 测试工具会很容易,但我还没有找到使用 vue 测试库来做到这一点的好方法。在使用 vue 测试库之前有没有人这样做过。
<template>
<v-data-table
data-testid="builds-table"
:headers="headers"
:items="builds"
:items-per-page="10"
class="elevation-1"
:loading="loading"
>
<template v-slot:[getItemStatus]=" item ">
<v-chip :color="getStatusColor(item.status)" dark>
item.status
</v-chip>
</template>
</v-data-table>
</template>
<script>
import mapState from "vuex";
import getScheduledBuilds from "../services/buildActivationService";
import getStatusColor from "../utils/getStatusColor";
export default
name: "BuildsTable",
data()
return
loading: false,
headers: [
text: "Activation Time",
align: "start",
value: "buildActivationTime",
,
text: "Build ID", value: "buildId" ,
text: "Build Label", value: "buildLabel" ,
text: "Status", value: "status" ,
],
error: "",
;
,
async mounted()
this.getBuilds();
,
computed:
...mapState(["brand", "builds"]),
getItemStatus()
return `item.status`;
,
,
watch:
brand()
this.getBuilds();
,
,
methods:
getStatusColor(status)
return getStatusColor(status);
,
async getBuilds()
try
this.loading = true;
const builds = await getScheduledBuilds(this.$store.getters.brand);
this.$store.dispatch("setBuilds", builds);
this.items = this.$store.getters.builds;
this.loading = false;
catch (error)
this.loading = false;
this.error = error.message;
this.$store.dispatch("setBuilds", []);
,
,
;
</script>
【问题讨论】:
【参考方案1】:Vue 测试库只是 Vue 测试实用程序的一个包装器,所以同样适用 call verification techniques。
以下是使用 Jest 和 Vue 测试库验证调用的方法:
Spy on组件方法定义之前渲染组件:
import render from '@testing-library/vue'
import BuildsTable from '@/components/BuildsTable.vue'
const getBuilds = jest.spyOn(BuildsTable.methods, 'getBuilds')
render(BuildsTable)
Render 具有给定存储和回调的组件,用于捕获被测 Vuex 存储实例:
let store =
state:
brand: '',
builds: [],
const storeCapture = (_, vuexStore) => store = vuexStore
render(BuildsTable, store , storeCapture)
更新商店的brand
值,并等待macro tick 让观察者生效,然后验证getBuilds
间谍被调用了两次(一次在mounted()
中,再次在brand
观察者中):
store.state.brand = 'foo'
await new Promise(r => setTimeout(r)) // wait for effect
expect(getBuilds).toHaveBeenCalledTimes(2)
完整的测试如下所示:
import render from '@testing-library/vue'
import BuildsTable from '@/components/BuildsTable.vue'
describe('BuildsTable.vue', () =>
it('calls getBuilds when brand changes', async() =>
const getBuilds = jest.spyOn(BuildsTable.methods, 'getBuilds')
let store =
state:
brand: '',
builds: [],
const storeCapture = (_, vuexStore) => store = vuexStore
render(BuildsTable, store , storeCapture)
store.state.brand = 'foo'
await new Promise(r => setTimeout(r)) // wait for effect
expect(getBuilds).toHaveBeenCalledTimes(2)
)
)
【讨论】:
以上是关于使用 vue-testing-library 测试 vue 观察者的主要内容,如果未能解决你的问题,请参考以下文章
如何在 testRigor 的一个测试中使用测试套件之前和测试套件之后?