带有Jest的Vuex-此.$store.getters.< getterName>不是函数

jhdbpxl9  于 2022-11-17  发布在  Vue.js
关注(0)|答案(4)|浏览(181)

我正在Vue中开发一个调查构建器,用户创建的调查问题将提交给Vuex,以便以后可以检索,如下所示:

computed: {
  inputs() {
    return this.$store.getters.questions(this.pageNumber);
  },
},

pageNumber是组件接收到的一个prop,inputs()返回一个问题数组。这看起来都能在屏幕上显示正确的问题,但是我在Jest测试中遇到了问题。
为了测试,我希望我可以用getter来模拟这个商店,就像我下面的尝试一样(省略了一些部分):

const localVue = createLocalVue();
localVue.use(Vuex);

beforeEach(() => {
  state = {
    survey: {
      pages: [
        // pages objects
      ],
    },
  };

  getters = {
    questions: () => [
      { type: 'Radio', config: { label: 'Test label', options: [{ label: 'Test option label' }] }, validation: [] },
    ],
  };

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

但这会导致错误:

TypeError: this.$store.getters.questions is not a function

但是,从getters.questions中删除箭头函数后,我得到了:

[vuex] getters should be function but "getters.questions" is [{"type":"Radio","config":{"label":"Test label","options":[{"label":"Test option label"}]},"validation":[]}].

所以我想我可能完全误会了。谁能给我指一下正确的方向吗?

2izufjch

2izufjch1#

存储区的getter就像组件上的计算属性一样,它们使用函数定义,但作为属性访问,没有括号。
给定以下行:

return this.$store.getters.questions(this.pageNumber);

questions getter返回一个接受pageNumber的函数,这不是当前在测试getter中定义的函数,只是返回一个数组。
因此,调用需要更改为使用方括号:

return this.$store.getters.questions[this.pageNumber];

或者getter需要返回一个函数:

getters = {
    questions: () => () => [
        { type: 'Radio', config: { label: 'Test label', options: [{ label: 'Test option label' }] }, validation: [] }
    ]
};

如果有助于澄清,这相当于:

getters = {
    questions: function () {
        return function () {
            const questions = [
                { type: 'Radio', config: { label: 'Test label', options: [{ label: 'Test option label' }] }, validation: [] }
            ];

            return questions;
        };
    }
};

请注意,我完全忽略了传递的pageNumber,因为我假设您的测试getter是硬编码的,以返回正确的问题数组。
您可能希望参考这个getter的非测试版本,因为我希望您会看到它返回额外级别的函数。

niwlg2el

niwlg2el2#

在vue-test-utils和Jest下,如果用以下代码替换模拟的存储,你可以很容易地模拟getter(特别是深嵌套模块getter):

方法#1
store: new Vuex.Store({
    getters: {
        'top-level-module/nested-module-level-1/more-nested-module/dataItem': function () {
            return 'any fake data you want'
        }
    }
}),

如果你只是想在模拟的getter上测试一个组件(比如说你从组件的computed中的嵌套存储模块获取值),这个解决方案意味着你不必编写深度嵌套存储对象的模拟。只需从模拟getter返回你喜欢的fake(!)对象。
请注意,如果不测试存储状态,则不需要模拟存储状态。
在这个测试中也不要测试getter的返回对象,将它提取到单独的专用测试中。

方法2

您甚至不需要Vuex,只需使用vue-test-utils模拟,如下所示:

mocks: {
    $store: {
        getters: {
            'top-level-module/nested-module-level-1/more-nested-module/dataItem': (function () {
                return 'any fake data you want'
            })()
        }
    }
},

请注意,与方法1相比,您必须将mock getter设置为IIFE,以便从mock获取值,因为mock不会像Vuex那样调用getter。

o2gm4chl

o2gm4chl3#

在getter中编写questions方法,如下所示:

getters = {
        questions: (state) => (page_number)=>{ [
          { type: 'Radio', config: { label: 'Test 
               label', 
           options: [{ label: 'Test option label' }] 
           }, 
           validation: [] },
        ],
         }
      };
mwngjboj

mwngjboj4#

在我的例子中,我创建了一个新模块,但是我忘记在index.js文件中注册它。

  • src/store/modules* 中的新文件:entities.js

然后在index.js文件中:

import entities from "./modules/entities";

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    ...
    entities,
  },
});

相关问题