Vue 测试库不会在状态更改时重新呈现 DOM
Vue Testing Library won't rerender DOM when state changes
我有一个带有直接编辑按钮的组件。 “编辑”按钮调用一个方法,将 isEditing
设置为 true
。
有几个输入元素带有 v-if="isEditing"
,因此我正在测试这些输入元素在单击“编辑”按钮后是否可见。
当我的测试运行 fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
时,它正在将 isEditing
更新为真(基于我的 console.log 消息 before/after .click
事件),但是它似乎没有重新呈现测试中的组件(基于 getByRole 失败后在我的终端中呈现的 DOM)。
它在浏览器中按预期工作,但似乎没有更新规范的 DOM。我正在使用 Vue2、Vue 测试库和 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()
})
})
它不起作用,因为你在应该 v-if
的时候写了 :v-if
。我想这只是一个错字,因为你第一次就正确地做到了 (v-if="!isEditing"
)
问题是在 DOM 有机会更新之前,您的期望是 运行。来自 testing library documentation:
Because Vue applies DOM updates asynchronously during re-renders, the fireEvent tools are re-exported as async functions. To ensure that the DOM is properly updated in response to an event in a test, it's recommended to always await fireEvent.
您应该像这样更新您的测试以等待 fireEvent 承诺:
it('displays input tags' async () => {
await fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
expect(screen.getByRole('input')).toBeInTheDocument()
})
正如 Nicole 在她的回答中指出的那样,您在第二个 v-if 中也有错字。
我有一个带有直接编辑按钮的组件。 “编辑”按钮调用一个方法,将 isEditing
设置为 true
。
有几个输入元素带有 v-if="isEditing"
,因此我正在测试这些输入元素在单击“编辑”按钮后是否可见。
当我的测试运行 fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
时,它正在将 isEditing
更新为真(基于我的 console.log 消息 before/after .click
事件),但是它似乎没有重新呈现测试中的组件(基于 getByRole 失败后在我的终端中呈现的 DOM)。
它在浏览器中按预期工作,但似乎没有更新规范的 DOM。我正在使用 Vue2、Vue 测试库和 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()
})
})
它不起作用,因为你在应该 v-if
的时候写了 :v-if
。我想这只是一个错字,因为你第一次就正确地做到了 (v-if="!isEditing"
)
问题是在 DOM 有机会更新之前,您的期望是 运行。来自 testing library documentation:
Because Vue applies DOM updates asynchronously during re-renders, the fireEvent tools are re-exported as async functions. To ensure that the DOM is properly updated in response to an event in a test, it's recommended to always await fireEvent.
您应该像这样更新您的测试以等待 fireEvent 承诺:
it('displays input tags' async () => {
await fireEvent.click(screen.getByRole('link', {name: 'Edit'}))
expect(screen.getByRole('input')).toBeInTheDocument()
})
正如 Nicole 在她的回答中指出的那样,您在第二个 v-if 中也有错字。