Vue 检查动作是否使用 spyOn 调用其他动作
Vue checking if action calls other action with spyOn
在 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.
我还有其他地方想测试这些类型的集成(一个调用另一个的操作),但它仍然给我这个错误。
只测试你的代码,而不是 vuex 的
这种测试的问题在于,您正在测试 vuex 是否按预期工作,这可能毫无价值。
不是直接监视 actions
,而是断言 vuex 在调用 dispatch('getRecipe', fruit)
时正确调用 getRecipe
动作,我会测试 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,然后将 vuex 加载到您的应用程序中:
new Vue({store})
因此,在您的测试中,actions
模块确实对 vuex 本身一无所知(这里我真的猜测,无法从您发布的代码中真正分辨出来,但很有可能)。
这就是为什么你的测试没有按预期工作,因为在测试中 getRecipes
方法只是获取一个 dispatch
参数并调用它,但是 vuex 并没有真正在那里做任何事情,所以有dispatch
调用不可能调用另一个操作。
现在,如果你仍然想用 jest 测试它,你应该从一个组件来做,所以你是在 vue 和 vuex 的上下文中测试这些动作。
关于这个有一个很好的教程in the vue test utils documentation。
当您尝试测试 async
功能时,您需要使用 await
const getAsyncWithSpyOn = spyOn(actions, 'getRecipe');
expect(await getAsyncWithSpyOn()).toHaveBeenCalledTimes(3)
在 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.
我还有其他地方想测试这些类型的集成(一个调用另一个的操作),但它仍然给我这个错误。
只测试你的代码,而不是 vuex 的
这种测试的问题在于,您正在测试 vuex 是否按预期工作,这可能毫无价值。
不是直接监视 actions
,而是断言 vuex 在调用 dispatch('getRecipe', fruit)
时正确调用 getRecipe
动作,我会测试 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,然后将 vuex 加载到您的应用程序中:
new Vue({store})
因此,在您的测试中,actions
模块确实对 vuex 本身一无所知(这里我真的猜测,无法从您发布的代码中真正分辨出来,但很有可能)。
这就是为什么你的测试没有按预期工作,因为在测试中 getRecipes
方法只是获取一个 dispatch
参数并调用它,但是 vuex 并没有真正在那里做任何事情,所以有dispatch
调用不可能调用另一个操作。
现在,如果你仍然想用 jest 测试它,你应该从一个组件来做,所以你是在 vue 和 vuex 的上下文中测试这些动作。
关于这个有一个很好的教程in the vue test utils documentation。
当您尝试测试 async
功能时,您需要使用 await
const getAsyncWithSpyOn = spyOn(actions, 'getRecipe');
expect(await getAsyncWithSpyOn()).toHaveBeenCalledTimes(3)