如何测试 Vuetify VHover?
Posted
技术标签:
【中文标题】如何测试 Vuetify VHover?【英文标题】:How to test Vuetify VHover? 【发布时间】:2019-06-14 08:39:02 【问题描述】:我创建了以下包含 Vuetify VHover、VTooltip 和 VBtn 的组件来简化我的应用程序。
<template>
<div>
<v-hover v-if="tooltip">
<v-tooltip
slot-scope=" hover "
bottom
>
<v-btn
slot="activator"
:theme="theme"
:align="align"
:justify="justify"
:disabled="disabled"
:depressed="type === 'depressed'"
:block="type === 'block'"
:flat="type === 'flat'"
:fab="type === 'fab'"
:icon="type === 'icon'"
:outline="type === 'outline'"
:raised="type === 'raised'"
:round="type === 'round'"
:color="hover ? colorHover : color"
:class=" 'text-capitalize': label, 'text-lowercase': icon "
:size="size"
@click="onClick()"
>
<span v-if="label"> label </span>
<v-icon v-else> icon </v-icon>
</v-btn>
<span> tooltip </span>
</v-tooltip>
</v-hover>
<v-hover v-else>
<v-btn
slot-scope=" hover "
:theme="theme"
:align="align"
:justify="justify"
:disabled="disabled"
:depressed="type === 'depressed'"
:block="type === 'block'"
:flat="type === 'flat'"
:fab="type === 'fab'"
:icon="type === 'icon'"
:outline="type === 'outline'"
:raised="type === 'raised'"
:round="type === 'round'"
:color="hover ? colorHover : color"
:class=" 'text-capitalize': label, 'text-lowercase': icon "
:size="size"
@click="onClick()"
>
<span v-if="label"> label </span>
<v-icon v-else> icon </v-icon>
</v-btn>
</v-hover>
</div>
</template>
<script>
import VueTypes from 'vue-types'
export default
name: 'v-btn-plus',
props:
align: VueTypes.oneOf(['bottom', 'top']),
justify: VueTypes.oneOf(['left', 'right']),
color: VueTypes.string.def('primary'),
colorHover: VueTypes.string.def('secondary'),
disabled: VueTypes.bool.def(false),
icon: VueTypes.string,
label: VueTypes.string,
position: VueTypes.oneOf(['left', 'right']),
tooltip: VueTypes.string,
size: VueTypes.oneOf(['small', 'medium', 'large']).def('small'),
theme: VueTypes.oneOf(['light', 'dark']),
type: VueTypes.oneOf(['block', 'depressed', 'fab', 'flat', 'icon', 'outline', 'raised', 'round']).def('raised')
,
methods:
onClick()
this.$emit('click')
,
created: function()
// Workaround as prop validation on multiple props is not possible
if (!this.icon && !this.label)
console.error('[Vue warn]: Missing required prop, specify at least one of the following: "label" or "icon"')
</script>
<style scoped>
</style>
我想测试 VHover 和 VTooltip 并定义了以下规范文件。
import createLocalVue, mount from '@vue/test-utils'
import Vuetify from 'vuetify'
import VBtnPlus from '@/components/common/VBtnPlus.vue'
describe('VStatsCard.vue', () =>
let localVue = null
beforeEach(() =>
localVue = createLocalVue()
localVue.use(Vuetify)
)
it('renders with default settings when only label is specified', async () =>
const label = 'Very cool'
const defaultColor = 'primary'
const defaultType = 'raised'
const defaultSize = 'small'
const wrapper = mount(VBtnPlus,
localVue: localVue,
propsData: label
)
expect(wrapper.text()).toMatch(label)
expect(wrapper.html()).toContain(`$defaultType="true"`)
expect(wrapper.html()).toContain(`size="$defaultSize"`)
expect(wrapper.html()).toContain(`class="v-btn theme--light $defaultColor text-capitalize"`)
expect(wrapper.html()).not.toContain(`v-icon"`)
wrapper.find('button').trigger('mouseenter')
await wrapper.vm.$nextTick()
const btnHtml = wrapper.find('.v-btn').html()
expect(btnHtml).toContain('secondary')
expect(btnHtml).not.toContain('primary')
const tooltipId = btnHtml.match(/(data-v-.+?)(?:=)/)[1]
const tooltips = wrapper.findAll('.v-tooltip_content')
let tooltipHtml = null
for (let tooltip of tooltips)
const html = tooltip.html()
console.log(html)
if (html.indexOf(tooltipId) > -1)
tooltipHtml = html
break
expect(tooltipHtml).toContain('menuable_content_active')
)
)
wrapper.find('button').trigger('mouseenter')
无法按预期工作。当我查看nextTick
之后的html 代码时,它与调用trigger
之前相同。看起来我错过了 html 的一部分。我期待看到以下 html。
<div data-v-d3e326b8="">
<span data-v-d3e326b8="" class="v-tooltip v-tooltip--bottom">
<span>
<button data-v-d3e326b8="" type="button" class="v-btn v-btn--depressed theme--light orange text-lowercase" size="small">
<div class="v-btn__content"><i data-v-d3e326b8="" aria-hidden="true" class="v-icon mdi mdi-account theme--light"></i></div>
</button>
</span>
</span>
</div>
我得到的只是<button>
部分。
有什么建议可以让它工作吗?
【问题讨论】:
出于兴趣,测试悬停组件的结果是什么,因为 Vuetify 已经对其组件进行了测试。 好问题 :-) 一是我想了解它如何与 vue-test-utils 一起工作,二是我想确保我可以自信地更改我的组件并升级 Vuetify,现在我的组件仍然有效,因为测试通过了。 在我看来,如果您使用的是像 vuetify 这样的第三方库。我会把测试留在他们手中。在重大更新之前,他们清楚地指出哪些更改是破坏性更改。如果您想创建测试,将这些时间花在您的核心应用程序上会更有用,而不是花在已经有测试的第三方库上。我真的鼓励进行测试!但有用的测试。我所说的一切都是基于个人的感受和经验。 【参考方案1】:https://github.com/vuejs/vue-test-utils/issues/1421
it('2. User interface provides one help icon with tooltip text', async (done) =>
// stuff
helpIcon.trigger('mouseenter')
await wrapper.vm.$nextTick()
requestAnimationFrame(() =>
// assert
done()
)
)
【讨论】:
请考虑为您的回答添加一些解释。谢谢【参考方案2】:我自己使用 Nuxt、Vuetify 和 Jest 时遇到了这个问题。我跟着 this example 用于 Vuetify 2.x。
下面是我对代码所做的一个非常简单的示例。
附带说明,当我尝试直接设置 wrapper.vm.[dataField] = [value]
时,Jest 抛出了一个错误,不允许直接 set
访问对象。在下面的 example.spec.js 中,调用 wrapper.setData(...)
将允许您毫无问题地设置数据值。
example.vue:
<template lang="pug">
v-hover(
v-slot:default=" hover "
:value="hoverActive"
)
v-card#hoverable-card(
:elevation="hover ? 20 : 10"
)
</template>
<script>
export default
data()
return
hoverActive: false
</script>
example.spec.js
import mount, createLocalVue from '@vue/test-utils'
import Vuetify from 'vuetify'
import example from '@/components/example.vue'
const localVue = createLocalVue()
localVue.use(Vuetify)
describe('example', () =>
const wrapper = mount(example,
localVue
)
it('should have the correct elevation class on hover', () =>
let classes = wrapper.classes()
expect(classes).toContain('elevation-10')
expect(classes).not.toContain('elevation-20')
wrapper.setData( hoverActive: true )
classes = wrapper.classes()
expect(classes).not.toContain('elevation-10')
expect(classes).toContain('elevation-20')
)
)
【讨论】:
谢谢。所以你只是为了测试目的将“hoverActive”变量添加到视图中?还是因为其他原因,您已经在课堂上设置了 hoverActive? v-slot:default=" hover " 监听是否悬停在生成的元素上。我根据 Vuetify 文档创建了模板。我遇到的一个问题是我无法让 v-hover 在测试中与模拟的鼠标悬停一起工作。但是,我知道我可以更改链接数据值并验证类更改。但是,为了回答您的问题,这是我的模板的简化示例以及用于测试模板的测试。【参考方案3】:显式触发mouseenter
事件通常不会产生影响,可能是因为browsers ignore simulated/non-trusted events。相反,您可以将v-hover
的value
设置为true
以强制悬停状态:
VBtnPlus.vue
<template>
<div>
<v-hover :value="hovering">...</v-hover>
</div>
</template>
<script>
export default
data()
return
hovering: false,
,
//...
</script>
VBtnPlus.spec.js
it('...', async () =>
wrapper.vm.hovering = true;
// test for hover state here
)
【讨论】:
以上是关于如何测试 Vuetify VHover?的主要内容,如果未能解决你的问题,请参考以下文章
Vue test-utils 如何使用 vuetify 测试导航栏按钮