【问题标题】:How to test a Vuex module action is called in Vue component mounted function?如何测试在 Vue 组件挂载函数中调用了 Vuex 模块操作?
【发布时间】:2021-07-27 04:08:05
【问题描述】:

我有一个像这样的 Vue 组件...

<template>
  <div class="mapdiv"></div>
</template>

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { mapViewModule } from "@/store/modules/MapViewModule";

@Component
export default class GeospatialMap extends Vue {
  async mounted(): Promise<void> {
    mapViewModule.initializeMapView(this.$el as HTMLDivElement);
  }
}
</script>

<style scoped>
.mapdiv {
  height: 700px;
  width: 1000px;
}
</style>

...我正在尝试测试 mapViewModule.initalizeMapView 函数是否被调用,这是我的 Vuex 模块中的一个操作。

我正在使用 Jest 并查看了其他答案,例如:https://stackoverflow.com/a/66987942/2052752 但没有运气......

import { shallowMount, createLocalVue } from "@vue/test-utils";
import Vuex from "vuex";
import GeospatialMap from "@/components/Geospatial.vue";

describe("GeospatialMap - ", () => {
  const localVue = createLocalVue();
  localVue.use(Vuex);
  const modules = {
    mapViewModule: {
      state: {},
      actions: {
        initializeMapView: jest.fn()
      },
      namespaced: true
    }
  };
  const store = new Vuex.Store({ modules });

  shallowMount(GeospatialMap, { localVue, store });

  it("when component created, initializes the map view", async () => {
    expect(modules.mapViewModule.actions.initializeMapView).toHaveBeenCalled();
  });
});

简单地说...... jest.fn 说它没有在控制台中调用......

expect(jest.fn()).toHaveBeenCalled()

    Expected number of calls: >= 1
    Received number of calls:    0

我不确定哪里出了问题。我不是在嘲笑模块操作吗?

我只是想测试初始化​​这个组件时是否调用了 Vuex 操作。

【问题讨论】:

    标签: vue.js jestjs vuex vue-test-utils vuex-modules


    【解决方案1】:

    是的,你没有在嘲笑商店。而且我还想说,您使用商店的方式有点奇怪,但这取决于您。

    我对组件进行了一些更改,以尽可能清楚地确定您的问题。

    <template>
      <div class="mapdiv">
        I am
      </div>
    </template>
    
    <script lang="ts">
    import Vue from 'vue'
    import Component from 'vue-class-component'
    import { mapViewModule } from '@/helpers/someModule' // there you put your path to the module
    
    @Component
    export default class GeospatialMap extends Vue {
      mounted (): void {
        mapViewModule.initializeMapView(this.$el as HTMLDivElement)
      }
    }
    </script>
    
    <style scoped>
    .mapdiv {
      height: 700px;
      width: 1000px;
    }
    </style>
    

    当您在 mount 钩子中调用 mapViewModule.initializeMapView 时,您只是在使用简单的 js 函数,所以我尝试通过在 @/helpers/ 中创建带有 someModule.ts 文件的 __mock__ 文件夹和代码来模拟该调用下面:

    // @/helpers/__mock__/someModule.ts
    export const mapViewModule = {
      initializeMapView: jest.fn((el: HTMLDivElement) => console.log('I am MOCK!!!', el))
    }
    

    然后在spec-file 中,我们必须告诉 Jest 使用我们的模拟文件而不是像这样的真实文件:

    import { shallowMount, Wrapper } from '@vue/test-utils'
    import GeospatiaMap from '@/components/GeospatiaMap/GeospatiaMap.vue'
    import { mapViewModule } from '@/helpers/someModule'
    
    jest.mock('../../helpers/someModule.ts') // there you put your path to module you want to mock
    let wrapper: Wrapper<GeospatiaMap & { [key: string]: any }>
    
    describe('GeospatiaMap.vue', () => {
      test('initializeMapView was called', () => {
        wrapper = shallowMount(GeospatiaMap) // wrapper property is useless now but you can use it your future tests
        expect(mapViewModule.initializeMapView).toBeCalled()
      })
    })
    

    就是这样。希望对您有所帮助。

    【讨论】:

    • 啊谢谢你的工作!好吧,必须专注于如何模拟更多。
    • 很高兴有帮助!顺便说一句,我从 Edd Yerburgh 的“测试 Vue.js 应用程序”中得到了这个技巧。
    猜你喜欢
    • 2019-08-16
    • 2020-02-29
    • 1970-01-01
    • 2021-09-21
    • 2018-04-25
    • 2019-10-18
    • 2016-08-28
    • 2020-09-22
    • 2018-12-21
    相关资源
    最近更新 更多