如何在 Mocha 单元测试中访问命名空间的 Vuex getter

Posted

技术标签:

【中文标题】如何在 Mocha 单元测试中访问命名空间的 Vuex getter【英文标题】:How to access namespaced Vuex getters in Mocha unit test 【发布时间】: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 未定义。

【问题讨论】:

【参考方案1】:

modulesnamespaced: 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 的不同属性下,并相应地分配给每个模块。

【讨论】:

这是正确的解决方案。太感谢了!我为此奋斗了几天。

以上是关于如何在 Mocha 单元测试中访问命名空间的 Vuex getter的主要内容,如果未能解决你的问题,请参考以下文章

Egg.js 单元测试入门

单元测试 WCF 服务时,AddressAccessDeniedException“您的进程没有访问此命名空间的权限”

使用proxyquire和mocha在单元测试中模拟方法调用时如何模拟时间延迟(超时)?

Vue,vuex:如何使用命名空间存储和模拟对组件进行单元测试?

前端单元测试框架-Mocha

windows下怎么用mocha进行单元测试