Библиотека тестирования Vue не будет повторно отображать DOM при изменении состояния
У меня есть компонент с прямой кнопкой Edit. Кнопка «Изменить» вызывает метод, для которого устанавливается значение
true
.
Есть несколько элементов ввода с
v-if="isEditing"
, поэтому я проверяю, видны ли эти элементы ввода после нажатия кнопки «Изменить».
Когда мой тест запускается
fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
, это обновление
isEditing
в true (на основе моих сообщений console.log до / после
.click
event), но, похоже, он не отображает компоненты в тесте повторно (на основе DOM, отображаемого в моем терминале после сбоя getByRole).
Он работает в браузере, как ожидалось, но, похоже, не обновляет DOM для спецификации. Я использую Vue2, Vue Testing Library и Jest.
Реализация:
<template>
<a @click.prevent="startEdit" v-if="!isEditing">Edit</a>
<input :v-if="isEditing" />
</template>
...
methods: {
startEdit: () => {
this.isEditing = true
}
}
Спецификация:
describe('FormComponent', () => {
beforeEach(() => {
render(FormComponent)
})
it('displays input tags' () => {
fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
expect(screen.getByRole('input')).toBeInTheDocument()
})
})
2 ответа
Проблема в том, что ваше ожидание выполняется до того, как DOM успел обновиться. Из документации библиотеки тестирования :
Поскольку Vue применяет обновления DOM асинхронно во время повторного рендеринга, инструменты fireEvent реэкспортируются как асинхронные функции. Чтобы обеспечить правильное обновление DOM в ответ на событие в тесте, рекомендуется всегда ждать fireEvent.
Вы должны обновить свой тест, чтобы дождаться обещания fireEvent следующим образом:
it('displays input tags' async () => {
await fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
expect(screen.getByRole('input')).toBeInTheDocument()
})
У вас также есть опечатка во втором v-if, как указала Николь в своем ответе.
Это не работает, потому что вы написали
:v-if
когда это должно быть
v-if
. Я предполагаю, что это была просто опечатка, так как вы сделали это правильно в первый раз (
v-if="!isEditing"
)