【问题标题】:How to access namespaced Vuex getters in Mocha unit test如何在 Mocha 单元测试中访问命名空间的 Vuex getter
【发布时间】:2019-10-16 12:51:14
【问题描述】:

我正在构建一个新的 Vue 组件,它使用命名空间的 Vuex getter 来访问列名列表。实际的组件编译并运行。

在我的 Mocha 单元测试中,我创建了一个模拟的 getter,它返回一个名为“allColumns”的字符串列表。当我运行单元测试时,在 ShallowMount 期间,组件的方法尝试在初始化期间访问 this.allColumns,但该值始终未定义。我可以在 this.$store.getters.allColumns 中看到我想要的值,但它并没有像我在浏览器中打开页面时那样映射到 this.allColumns。

有很多关于如何在测试中模拟 getter 以及如何将 mapGetters 与命名空间一起使用的信息,但我没有找到任何关于 Mocha 测试中命名空间 getter 的文档。

test.spec.js

  let propsData;
  let getters;
  let store;

  beforeEach(() => {
    debugger;
    propsData = {
      players: samplePlayerObject,
      metadata: sampleMetadataObject
    };

    getters = {
      allColumns: () => ["playerid","last","first","birthday","height"]
    }

    store = new Vuex.Store({
      getters
    });
  })

  it('initializes the component', () => {
    const wrapper = shallowMount(PlayerFilterTable, { propsData, localVue, store });
  });

vue 组件


<template>
  <div class="player-filter-table">
    <table>
      <tr>
         <th v-for="(key, index) in GetColumns()" 
            v-bind:id="'header-' + key" 
            v-bind:key="index"
            @click="HeaderClick(key)"
          >...</th>
      </tr>
    </table>
  </div>
</template>

<script>
import { mapGetters } from 'vuex';
export default {
  computed: {
    ...mapGetters({
      allColumns: 'playerFilter/allColumns'
    })
  },
GetColumns() {
  // this.allColumns is defined when running in browser, but undefined when loaded from a Mocha test
  return this.allColumns.filter(column => [*some filter criteria*]);
}
</script>

当 shallowMount 在 test.spec.js 中运行时,我希望组件能够成功加载,然后继续运行我的测试,但是我收到一个错误,提示 TypeError: Cannot read property 'filter' of undefined because this。 allColumns 未定义。

【问题讨论】:

    标签: unit-testing vue.js mocha.js vuex


    【解决方案1】:

    将modules 与namespaced: true 一起使用:

    import { createLocalVue, shallowMount } from '@vue/test-utils';
    import Vuex from 'vuex';
    import PlayerFilterTable from '~/whatever';
    
    const localVue = createLocalVue();
    localVue.use(Vuex);
    
    let propsData, getters, store, wrapper, consoleSpy;
    
    describe('PlayerFilterTable', () => {
    
      beforeEach(() => {
        consoleSpy = jest.spyOn(console, 'error');
        propsData = {
          players: samplePlayerObject,
          metadata: sampleMetadataObject
        };
        getters = {
          allColumns: () => ["playerid", "last", "first", "birthday", "height"]
        };
        store = new Vuex.Store({
          modules: {
            playerFilter: {
              namespaced: true,
              getters
            }
          }
        });
        wrapper = shallowMount(PlayerFilterTable, {
          propsData,
          localVue,
          store
        });
      });
    
      afterEach(() => {
        expect(consoleSpy).not.toHaveBeenCalled();
      });
    
      it('should render correctly', () => {
        expect(wrapper.is(PlayerFilterTable)).toBe(true);
        expect(wrapper.html()).toMatchSnapshot();
      })
    })
    

    如果您使用来自多个模块的 getter,您可以将它们分组到 getters 的不同属性下,并相应地分配给每个模块。

    【讨论】:

    • 这是正确的解决方案。太感谢了!我为此奋斗了几天。
    猜你喜欢
    • 2017-12-21
    • 2020-06-27
    • 2014-10-01
    • 2018-03-08
    • 2023-04-09
    • 2020-09-29
    • 1970-01-01
    • 2011-06-26
    • 2021-05-19
    相关资源
    最近更新 更多