使用 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 的一个测试中使用测试套件之前和测试套件之后?

Linux在测试中的主要使用场景都有哪些?

使用[测试类]而不是[编码UI测试]时将测试用例与测试方法相关联

3 测试使用和LogCat日志