Проверка Vue, если действие вызывает другое действие с spyOn
В Vue я хочу проверить, правильно ли действие в моем магазине вызывает другое действие, используя Jest's 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.
У меня есть другие места, где я хочу протестировать такого рода интеграцию (действие, вызывающее другое), но это все равно дает мне эту ошибку.
2 ответа
Протестируйте только ваш код, а не vuex
Проблема с такого рода тестами заключается в том, что вы тестируете, что vuex работает как положено, что, вероятно, бесполезно.
Вместо того, чтобы шпионить прямо на actions
и утверждают, что vuex правильно вызывает getRecipe
действие, когда 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, а затем загружаете vuex в свое приложение с помощью:
new Vue({store})
Итак, в ваших тестах actions
Модуль действительно ничего не знает о самом vuex (здесь я догадываюсь, действительно, не могу сказать по вашему опубликованному коду, но это вероятно).
Вот почему ваши тесты не работают, как ожидалось, потому что в тесте getRecipes
метод просто получает dispatch
параметр и вызывает его, но vuex на самом деле ничего не делает там, так что нет никакого способа, которым dispatch
вызов будет вызывать другое действие.
Теперь, если вы все еще хотите протестировать это с помощью jest, вы должны сделать это из компонента, поэтому вы тестируете действия в контексте vue и vuex.
В документации утилиты vue test есть хорошее руководство по этому вопросу.
Когда вы пытаетесь проверить async
функция, которую вы должны использовать await
const getAsyncWithSpyOn = spyOn(actions, 'getRecipe');
expect(await getAsyncWithSpyOn()).toHaveBeenCalledTimes(3)