条件呈现
Vue Test Utils具有一系列功能,用于呈现和断言组件的状态,目的是验证组件的行为是否正确。本文将探讨如何呈现组件,以及验证它们是否正确地呈现了内容。
你也可以观看这个短视频。
查找元素
Vue最基本的功能之一是能够使用v-if动态插入和删除元素。让我们看看如何测试使用v-if的组件。
const Nav = {
template: `
<nav>
<a id="profile" href="/profile">My Profile</a>
<a v-if="admin" id="admin" href="/admin">Admin</a>
</nav>
`,
data() {
return { admin: false };
},
};const Nav = {
template: `
<nav>
<a id="profile" href="/profile">My Profile</a>
<a v-if="admin" id="admin" href="/admin">Admin</a>
</nav>
`,
data() {
return { admin: false };
},
};在<Nav>组件中,会显示到用户配置文件的链接。此外,如果admin值为true,我们将显示到admin部分的链接。我们应该验证以下三种情况是否正确:
- 应显示
/profile链接。 - 当用户是管理员时,应该显示
/admin链接。 - 如果用户不是管理员,则不应显示
/admin链接。
使用 get()
wrapper有一个用于搜索现有元素的get()方法。它使用querySelector语法。
我们可以使用get()断言概要文件链接内容:
test("renders a profile link", () => {
const wrapper = mount(Nav);
// Here we are implicitly asserting that the
// element #profile exists.
const profileLink = wrapper.get("#profile");
expect(profileLink.text()).toEqual("My Profile");
});test("renders a profile link", () => {
const wrapper = mount(Nav);
// Here we are implicitly asserting that the
// element #profile exists.
const profileLink = wrapper.get("#profile");
expect(profileLink.text()).toEqual("My Profile");
});如果get()没有返回与选择器匹配的元素,它将引发一个错误,并且您的测试将失败。如果找到元素,则get()返回一个DOMWrapper。DOMWrapper是实现wrapper API的DOM元素的包装器-这就是为什么我们能够执行profileLink.text()并访问文本。可以使用图元属性访问原始图元。
还有另一种类型的包装器——VueWrapper——它是从以相同方式工作的getComponent返回的。
使用 find() 和 exists()
get()的工作原理是假设元素确实存在,并在不存在时抛出错误。但是不建议使用它来断言存在。
为此,我们使用find()和exists()。下面的测试断言,如果admin为false(默认情况下为false),则不存在admin链接:
test("does not render an admin link", () => {
const wrapper = mount(Nav);
// Using `wrapper.get` would throw and make the test fail.
expect(wrapper.find("#admin").exists()).toBe(false);
});test("does not render an admin link", () => {
const wrapper = mount(Nav);
// Using `wrapper.get` would throw and make the test fail.
expect(wrapper.find("#admin").exists()).toBe(false);
});请注意,我们正在对.find()返回的值调用exists()。find()和mount()一样,也返回一个包装器。mount()有一些额外的方法,因为它包装了Vue组件,find()只返回一个常规 DOM 节点,但许多方法在两者之间共享。其他一些方法包括classes(),它获取DOM节点所具有的类,以及trigger(),用于模拟用户交互。您可以在此处找到支持的方法列表。
使用 data
最后一个测试是断言当admin为true时会呈现 admin 链接。默认情况下它是false,但我们可以使用mount()的第二个参数,即 mounting 选项来覆盖它。
对于数据,我们使用适当命名的数据选项:
test("renders an admin link", () => {
const wrapper = mount(Nav, {
data() {
return {
admin: true,
};
},
});
// Again, by using `get()` we are implicitly asserting that
// the element exists.
expect(wrapper.get("#admin").text()).toEqual("Admin");
});test("renders an admin link", () => {
const wrapper = mount(Nav, {
data() {
return {
admin: true,
};
},
});
// Again, by using `get()` we are implicitly asserting that
// the element exists.
expect(wrapper.get("#admin").text()).toEqual("Admin");
});如果你在数据中有其他属性,不要担心-Vue Test Utils 会将两者合并在一起。装载选项中的数据将优先于任何默认值。
要了解还存在哪些装载选项,请参阅传递数据或参阅装载选项。
检查元素可见性
有时,您只想隐藏/显示一个元素,同时将其保留在DOM中。Vue 为这样的场景提供了v-show。(您可以在此处查看v-if和v-show之间的差异)。
以下是带有v-show的组件的外观:
const Nav = {
template: `
<nav>
<a id="user" href="/profile">My Profile</a>
<ul v-show="shouldShowDropdown" id="user-dropdown">
<!-- dropdown content -->
</ul>
</nav>
`,
data() {
return {
shouldShowDropdown: false,
};
},
};const Nav = {
template: `
<nav>
<a id="user" href="/profile">My Profile</a>
<ul v-show="shouldShowDropdown" id="user-dropdown">
<!-- dropdown content -->
</ul>
</nav>
`,
data() {
return {
shouldShowDropdown: false,
};
},
};在这种情况下,元素不可见,但始终呈现。get()或find()将始终返回一个Wrapper()–find()with.exists()始终返回true,因为元素仍在 DOM 中。
使用 isVisiBle()
isVisible()提供了检查隐藏元素的能力。特别是isVisible()将检查是否:
- 元素或其祖先具有
display: none,visibility: hidden,opacity :0的样式 - 元素或其祖先位于折叠的< details >标记内
- 元素或其祖先具有隐藏属性
对于这些情况中的任何一种,isVisible()都返回false。
使用 v-show 的测试场景如下所示:
test("does not show the user dropdown", () => {
const wrapper = mount(Nav);
expect(wrapper.get("#user-dropdown").isVisible()).toBe(false);
});test("does not show the user dropdown", () => {
const wrapper = mount(Nav);
expect(wrapper.get("#user-dropdown").isVisible()).toBe(false);
});结论
- 使用
find()和exists()来验证元素是否在 DOM 中。 - 如果希望元素在
DOM中,请使用get()。 - 数据装载选项可用于设置零部件的默认值。
- 使用
get()和isVisible()来验证 DOM 中元素的可见性
zerone