在Vue中,我想检查商店中的某个动作是否使用Jest的spyOn
正确调用了另一个动作,我以不同的方式尝试了它,但似乎不起作用,这是我的代码:
// index.js
getRecipes ({ dispatch }) {
const fruits = ['apple', 'banana', 'pear']
fruits.forEach((fruit) => {
dispatch('getRecipe', fruit)
})
},
async getRecipe ({ commit }) {
const recipe = await recipesService.fetchRecipe(payload)
commit(SET_RECIPE, { recipe })
},
// index.spec.js
test('getRecipes calls getRecipe 3 times, each with the right fruit', () => {
const commit = jest.fn()
const dispatch = jest.fn()
const spy = spyOn(actions, 'getRecipe')
const result = actions.getRecipes({ commit, dispatch })
expect(spy).toHaveBeenCalledTimes(3)
expect(spy).toHaveBeenCalledWith('apple')
})
但是当我运行测试时,这是我得到的输出:
Expected spy to have been called three times, but it was called zero times.
我在其他地方想测试这些集成(一个动作调用另一个),但是它仍然给我这个错误。
答案 0 :(得分:1)
这种测试的问题在于,您正在测试vuex是否按预期工作,这可能毫无价值。
代替直接监视actions
并断言在调用getRecipe
时vuex正确调用了dispatch('getRecipe', fruit)
动作,我只测试getRecipes
动作的调用正确dispatch
:
test('getRecipes dispatches 3 "getRecipe" actions, each with the right fruit', () => {
const commit = jest.fn()
const dispatch = jest.fn()
const result = actions.getRecipes({ commit, dispatch })
expect(dispatch).toHaveBeenCalledTimes(3)
expect(dispatch.mock.calls[0][0]).toBe('apple')
expect(dispatch.mock.calls[1][0]).toBe('banana')
expect(dispatch.mock.calls[2][0]).toBe('pear')
})
您并没有真正展示如何导入和导出模块,但是我想在您的代码中,动作文件仅会导出带有动作的普通对象,而测试只会将其导入。
在您的应用程序代码中,可能是您正在将这些操作添加到vuex,然后使用以下命令将vuex加载到您的应用程序中:
new Vue({store})
因此,在您的测试中,actions
模块确实对vuex本身一无所知(在这里,我猜确实无法从您已发布的代码中真正看出来,但这很有可能)。
这就是您的测试无法按预期进行的原因,因为在测试中,getRecipes
方法仅获取了一个dispatch
参数并调用了该参数,但是vuex并没有真正做任何事情,因此没有dispatch
调用将调用另一个操作的方式。
现在,如果您仍然想开玩笑地对此进行测试,则应该从一个组件中进行操作,因此您要在vue和vuex的上下文中测试操作。
关于此in the vue test utils documentation的很好的教程。
答案 1 :(得分:0)
当您尝试测试async
功能时,您需要使用await
const getAsyncWithSpyOn = spyOn(actions, 'getRecipe');
expect(await getAsyncWithSpyOn()).toHaveBeenCalledTimes(3)