- 开始时间:2020-02-01
- 目标主要版本:VTU beta-0.3x/1.x
- 引用 issue:N/A
- 实现的 PR:N/A
摘要
允许 Vue Test Utils APIs awati 触发的重新渲染,这使得重新渲染后断言改变更容易。
基本范例
const wrapper = mount(Component)await wrapper.find('.element').trigger('click')expect(wrapper.emitted('event')).toBeTruthy()
动机
随着 Vue Test Utils beta-29 中 sync 模式的移除,我们现在需要 await 诸如观察者或模版重新渲染,然后再做断言。
这个提案的目的是让开发者更容易使用异步测试,允许你 await 像 trigger 或那些内部使用它的调用。
这个提案假定在测试中使用 async/await。
具体设计
一般的想法是,从触发异步变化的行为中返回一个在 NextTick 上 resolving 的 promise。
此时,我们需要手动 await 组件的更新。这导致了额外的模版,并且对初学者来说更难掌握。
const wrapper = mount(Component)wrapper.find('.element').trigger('click')// we need to wait for the component to renderawait wrapper.vm.$nextTick()expect(wrapper.emitted('event')).toBeTruthy()
新的 API 看起来像这样:
const wrapper = mount(Component)await wrapper.find('.element').trigger('click')expect(wrapper.emitted('event')).toBeTruthy()
使用更复杂的测试例子,好处是显而易见的:
await wrapper.find('.button').trigger('click')expect(wrapper.emitted('event')).toBeTruthy()await wrapper.find('.country-option').setValue('US')expect(wrapper.find('.state').exists()).toBe(true)await wrapper.find('.radio-option').setChecked()expect(wrapper.find('.finish').attributes('disabled')).toBeFalsy()
应该返回一个 promise 的方法,在 next tick 时解决:
- trigger
- setValue
- setChecked
- setData
- setProps
- setSelected
上述大多数 helper 在内部依赖于 trigger,所以更新大多数列出的方法很容易。
附加的 helper
目前我们已经看到了 3 种 await 变化的方式:
import flushPromises from 'flush-promises'await flushPromises()// or the more preferredawait wrapper.vm.$nextTick()await Vue.nextTick()
在 Vue 3 中,nextTick 将从 VM 实例中移除,所以用户必须迁移到直接从 Vue 导入它 import { nextTick } from 'vue'。
可以在 VTU 的 exports 中添加一个 tick helper。这样一来,用户就可以把所有东西都放在一个地方,并且有一个正式的方法来等待渲染,从不能直接返回一个 promise 的 actions 中。
这样的情况是触发了一个自定义的 Vue 事件:
import { mount, tick } from '@vue/test-utils'it('test' => {const wrapper = mount(Component)wrapper.find('.input').vm.$emit('input', 'Newly added note')await tick()expect(wrapper).toMatchSnapshot()})
或者,我们可以聚焦在一个元素的挂载上,这通常是在 next tick 时进行的:
const wrapper = mount(Component)// await data to be focused on mountedawait tick()let input = wrapper.find('input').elementexpect(input).toBe(document.activeElement)
缺点
现在每一个 trigger 都会调用 nextTick(),我不确定这是否会损害性能。
用户可能会尝试 await 任何与 DOM 交互的东西,所以写好文档和指南是一个问题。
备选方案
N/A
采纳策略
Vue Test Utils beta-30+
用户必须确保 async/await 在他们的测试环境中是有效的。
用户只需要删除额外的 $nextTick 和 flushPromise 调用,并使用新的 API。
改进关于该主题的文档。
Vue Test Utils prior to beta-30
在移除 sync 之前,没有必要等待渲染。
没有解决的问题
N/A
