#reactjs #jestjs #enzyme
#reactjs ( реакция ) #jestjs #фермент #reactjs
Вопрос:
Я пишу тест для async action creator, но столкнулся с проблемой, когда в нем указано, что «Ожидаемая функция макета была вызвана» с:
[{"type": "GET_LOGIN_SUCCESS", "value": true}]
Но она не была вызвана.
Я не уверен, в чем именно заключается проблема. Если кто-нибудь может помочь, это будет высоко оценено.
Вот мой actions.js
import { GET_LOGIN_SUCCESS } from './constants'
export const getLoginInfo = () => {
return (dispatch, getState, axiosInstance) => {
return axiosInstance.get('/api/isLogin.json')
.then((res) => {
dispatch({
type: GET_LOGIN_SUCCESS,
value: res.data.data.login
})
console.log('finishing dispatch')
})
}
}
actions.test.js
import { getLoginInfo } from './actions'
import { GET_LOGIN_SUCCESS } from './constants'
describe('async actions', () => {
it('dispatches GET_LOGIN_SUCCESS when getting login finishes', () => {
const axiosInstance = {
get: jest.fn(() => Promise.resolve({ data: { data: {login : true }}}))
}
const dispatch = jest.fn()
getLoginInfo()(dispatch, null, axiosInstance)
expect(dispatch).toHaveBeenCalledWith({
type: GET_LOGIN_SUCCESS,
value: true
})
})
})
Комментарии:
1. Может быть, попробуйте поместить
catch
вactions.js
иconsole.log
там, чтобы посмотреть, есть ли ошибка.
Ответ №1:
Проблема в том, что jest не может знать, что задействована асинхронная задача. Итак, в вашем случае вы создаете макет, который возвращает обещание, и отправка вызывается, когда обещание выполнено. Поскольку JavaScript является однопоточным, он сначала оценивает код в тесте, а все асинхронные задачи выполняются впоследствии. Итак, вам нужно ознакомить jest с обещанием, используя async/await
:
describe('async actions', () => {
it('dispatches GET_LOGIN_SUCCESS when getting login finishes', async() => {
const p = Promise.resolve({ data: { data: {login : true }}}))
const axiosInstance = {
get: jest.fn(() => p
}
const dispatch = jest.fn()
getLoginInfo()(dispatch, null, axiosInstance)
await p // even it sounds not very logically you need to wait here
expect(dispatch).toHaveBeenCalledWith({
type: GET_LOGIN_SUCCESS,
value: true
})
})
Как указывает @brian-lives-outdoors, getLoginInfo
также возвращает обещание, поэтому вы также можете просто дождаться результата вызова:
it('dispatches GET_LOGIN_SUCCESS when getting login finishes', async() => {
const axiosInstance = {
get: jest.fn(() => Promise.resolve({ data: { data: {login : true }}}))
}
const dispatch = jest.fn()
await getLoginInfo()(dispatch, null, axiosInstance)
expect(dispatch).toHaveBeenCalledWith({
type: GET_LOGIN_SUCCESS,
value: true
})
})
Есть эпическая статья, которая описывает всю тему
Комментарии:
1. Функция, возвращаемая при вызове,
getLoginInfo
возвращаетPromise
, поэтому единственные необходимые изменения — создать тестовую функциюasync
и изменить эту одну строку наawait getLoginInfo()(dispatch, null, axiosInstance);
2. @brian-lives-outdoors верно, это тоже сработало бы. Я подумал, что это будет легче понять, когда можно будет увидеть, чего вам нужно ждать. Я обновлю свой ответ, чтобы отразить и ваше решение.
3. В дополнение к приведенным выше ответам, например, при рендеринге перехватов вы можете обернуть ожидаемую часть с
waitFor(() => expect(...));