Jest进阶:测试 Vue 组件

在 Vue 项目中,测试组件是确保应用质量和稳定性的关键步骤。Vue Test Utils 是一个专门为 Vue.js 应用程序编写的单元测试和集成测试工具库。它提供了丰富的 API,帮助开发者模拟用户操作、查询组件和断言测试结果,从而在不需要手动操作应用程序的情况下自动化地测试 Vue 组件的行为和交互。

安装 Vue Test Utils

首先,确保你已经安装了 Vue Test Utils。根据你使用的 Vue 版本,安装相应的 Vue Test Utils 版本:

  • Vue 2:

    npm install @vue/test-utils@1 --save-dev
    
  • Vue 3:

    npm install @vue/test-utils@next --save-dev
    
快速上手

假设我们有一个简单的 Vue 组件 HelloWorld.vue

<template><div class="hello"><h1>{{ msg }}</h1></div>
</template><script>
export default {name: 'HelloWorld',props: {msg: String}
}
</script>

接下来,我们编写测试代码:

import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue';describe('HelloWorld.vue', () => {it('renders props.msg when passed', () => {const msg = 'new message';const wrapper = shallowMount(HelloWorld, {props: { msg }});expect(wrapper.text()).toMatch(msg);});
});

在这个测试中,我们使用 shallowMount 渲染 HelloWorld 组件,并传递 msg 属性。然后,我们使用 expect 断言组件的文本内容是否包含传递的 msg

常用 API

Vue Test Utils 提供了许多有用的 API,以下是一些常用的 API:

  • find(selector): 查找匹配选择器的第一个元素。
  • findAll(selector): 查找匹配选择器的所有元素。
  • trigger(eventType, eventData): 触发组件的事件。
  • setProps(props): 设置组件的属性。
  • setData(data): 设置组件的数据。
  • text(): 获取组件的文本内容。
  • html(): 获取组件的 HTML 代码。
示例:测试 TodoList 组件

假设我们有一个 TodoList.vue 组件:

<template><div><div v-for="todo in todos" :key="todo.id" data-test="todo">{{ todo.text }}</div><form data-test="form" @submit.prevent="createTodo"><input data-test="new-todo" v-model="newTodo" /></form></div>
</template><script setup lang="ts">
import { ref } from 'vue';
const newTodo = ref('');
const todos = ref([{id: 1,text: 'Learn Vue.js 3',completed: false}
]);function createTodo() {todos.value.push({id: 2,text: newTodo.value,completed: false});newTodo.value = '';
}
</script>

接下来,我们编写测试代码:

import { shallowMount } from '@vue/test-utils';
import TodoList from '@/components/TodoList.vue';test('测试新增待办事项', async () => {const wrapper = shallowMount(TodoList);const todo = wrapper.get('[data-test="todo"]');expect(todo.text()).toBe('Learn Vue.js 3');// 模拟新增待办事项await wrapper.get('[data-test="new-todo"]').setValue('New To Do Item');await wrapper.get('[data-test="form"]').trigger('submit');// 断言新增的待办事项expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(2);
});
测试快照

生成测试快照代码如下:

expect(wrapper.element).toMatchSnapshot();
配置 Jest

如果你使用的是 Vue CLI 创建的项目,默认配置的 Jest 只检查 .spec 文件。如果想要检测 .test 类型的文件,需要在 jest.config.js 中进行配置:

module.exports = {// ...testMatch: ['**/tests/**/*.[jt]s?(x)','**/?(*.)+(spec|test).[jt]s?(x)']
};
更多示例
示例一:隐藏消息组件

组件代码:

<template><div><label htmlFor="toggle">显示说明</label><input id="toggle" type="checkbox" :checked="showMessage" @click="showMessage = !showMessage" /><div id="showMessage"><slot v-if="showMessage"></slot></div></div>
</template><script setup lang="ts">
import { ref } from 'vue';
const showMessage = ref(false);
</script>

测试代码:

import { shallowMount } from '@vue/test-utils';
import HiddenMessage from '@/components/HiddenMessage.vue';test('正确的渲染出来', () => {const wrapper = shallowMount(HiddenMessage);expect(wrapper.find('label').text()).toBe('显示说明');expect(wrapper.find('input').attributes('type')).toBe('checkbox');
});test('默认不显示信息', () => {const wrapper = shallowMount(HiddenMessage);expect(wrapper.find('#showMessage').exists()).toBe(true);expect(wrapper.find('#showMessage').text()).toBe('');
});test('点击复选框之后能够显示信息', async () => {const wrapper = shallowMount(HiddenMessage, {slots: {default: '<p>这是一段说明文字</p>'}});const checkbox = wrapper.find('input');await checkbox.trigger('click');expect(wrapper.find('#showMessage').text()).toBe('这是一段说明文字');await checkbox.trigger('click');expect(wrapper.find('#showMessage').text()).toBe('');
});
示例二:登录组件

组件代码:

<template><div><form @submit.prevent="handleSubmit"><div><label for="usernameInput">Username</label><input id="usernameInput" v-model="username" /></div><div><label for="passwordInput">Password</label><input id="passwordInput" type="password" v-model="password" /></div><button type="submit">Submit{{ state.loading ? '...' : null }}</button></form><div v-if="state.error" role="alert">{{ state.error }}</div><div v-if="state.resolved" role="alert">Congrats! You're signed in!</div></div>
</template><script setup lang="ts">
import { ref } from 'vue';interface LoginState {resolved: boolean;loading: boolean;error: string | null;
}const username = ref('');
const password = ref('');
const state = ref<LoginState>({resolved: false,loading: false,error: null,
});function handleSubmit() {state.value.loading = true;state.value.resolved = false;state.value.error = null;window.fetch('/api/login', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({username: username.value,password: password.value,}),}).then((r) =>r.json().then((data) => (r.ok ? data : Promise.reject(data)))).then((user) => {state.value.loading = false;state.value.resolved = true;state.value.error = null;localStorage.setItem('token', user.token);},(error) => {state.value.loading = false;state.value.resolved = false;state.value.error = error.message;});
}
</script>

测试代码:

import { shallowMount } from '@vue/test-utils';
import Login from '@/components/Login.vue';const fakeUserResponse = { token: 'fake_user_token' };
window.fetch = jest.fn().mockResolvedValue({ok: true,json: () => Promise.resolve(fakeUserResponse),
});afterEach(() => {window.localStorage.removeItem('token');
});test('请求成功', async () => {const wrapper = shallowMount(Login);await wrapper.find('#usernameInput').setValue('xiejie');await wrapper.find('#passwordInput').setValue('123456');await wrapper.find('form').trigger('submit');await wrapper.vm.$nextTick();await new Promise((resolve) => setTimeout(resolve, 100));expect(window.localStorage.getItem('token')).toEqual(fakeUserResponse.token);expect(wrapper.find('[role="alert"]').text()).toMatch(/Congrats/i);
});test('请求失败', async () => {window.fetch = jest.fn().mockResolvedValue({ok: true,json: () =>Promise.reject({message: '服务器内部错误',}),});const wrapper = shallowMount(Login);await wrapper.find('#usernameInput').setValue('xiejie');await wrapper.find('#passwordInput').setValue('123456');await wrapper.find('form').trigger('submit');await wrapper.vm.$nextTick();await new Promise((resolve) => setTimeout(resolve, 100));expect(window.localStorage.getItem('token')).toBeNull();expect(wrapper.find('[role="alert"]').text()).toMatch('服务器内部错误');
});

总结

本节介绍了如何使用 Vue Test Utils 测试 Vue 组件。Vue Test Utils 提供了一系列强大的 API,帮助开发者模拟用户操作、查询组件和断言测试结果,从而确保 Vue 应用程序的稳定性和可靠性。通过合理的测试,可以捕获潜在的问题,提高代码质量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/464918.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序-事件总线

一.事件总线的概念和作用 事件总线是对发布-订阅模式的一种实现&#xff0c;是一种集中式事件处理机制&#xff0c;允许不同组件之间进行彼此通信&#xff0c;常用于两个非父子组件和兄弟组件之间的通讯。 在日常开发过程中&#xff0c;我们可以使用第三方的发布订阅 JS 包来实…

成都郝蓉宜恺文化传媒:引领大数据应用新篇章

在信息化浪潮汹涌的今天&#xff0c;大数据被誉为新时代的“石油”&#xff0c;正在以前所未有的速度改变着我们的生活和工作方式。成都郝蓉宜恺文化传媒&#xff0c;作为大数据领域的领军企业&#xff0c;始终站在创新的前沿&#xff0c;引领着大数据应用的新篇章。 作为大数…

qt QDropEvent详解

1、概述 QDropEvent是Qt框架中用于处理拖放释放事件的一个类。它允许开发者在用户界面中更好地管理和处理拖放操作&#xff0c;从而实现交互式和响应式的应用程序。QDropEvent类提供了处理拖放释放事件所需的方法和信号&#xff0c;使得开发者能够轻松地实现拖放功能&#xff…

Kotlin的内置函数

Kotlin 提供了丰富的内置函数&#xff0c;它们极大简化了日常开发工作。常见内置函数包括 标准库函数&#xff08;let、apply、run 等&#xff09;&#xff0c;用于提高代码的简洁性和可读性。下面我们详细介绍这些函数的功能、用法以及它们之间的区别。 1. let 函数 let 通常…

Pod安装软件将CDN改为国内的镜像

1、碰到错误 在pod install的时候碰到以下的下载错误&#xff1a; 文字错误如下&#xff1a; CDN: trunk URL couldnt be downloaded: https://cdn.jsdelivr.net/cocoa/Specs/5/b/d/OpenCV/2.4.11/OpenCV.podspec.json Response: Timeout was reached CDN: trunk URL couldn…

Rockchip SoC AI 与视觉处理器路线图:赋能未来的 AI 驱动设备

随着人工智能&#xff08;AI&#xff09;和计算机视觉技术不断推动各行各业的创新&#xff0c;Rockchip 已成为提供强大系统级芯片&#xff08;SoC&#xff09;解决方案的领先厂商。该公司已开发出多款集成 AI 功能并支持先进多媒体与视觉技术的 SoC&#xff0c;非常适合用于 A…

尚庭公寓-小程序接口

7. 项目开发 7.4 移动端后端开发 7.4.1 项目初始配置 7.4.1.1 SpringBoot配置 1. 创建application.yml文件 在web-app模块的src/main/resources目录下创建application.yml配置文件&#xff0c;内容如下&#xff1a; server:port: 80812. 创建SpringBoot启动类 在web-app…

练习LabVIEW第三十八题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十八题&#xff1a; 创建一个VI&#xff0c;实现对按钮状态的指示和按钮“按下”持续时间简单计算功能&#xff0c;按…

HTMLCSS:3D 旋转卡片的炫酷动画

效果演示 这段代码是一个HTML和CSS的组合&#xff0c;用于创建一个具有3D效果的动画卡片。 HTML <div class"obj"><div class"objchild"><span class"inn6"><h3 class"text">我是谁&#xff1f;我在那<…

微控制器(MCU)如何运行存储在Flash的程序???

忙&#xff0c;太忙了&#xff01;&#xff01;&#xff01;忙完就好了。MCU运行不也就如此&#xff1f;在微控制器单元&#xff08;MCU&#xff09;中&#xff0c;我们所编写的程序时通常是存储在闪存&#xff08;Flash&#xff09;中。当MCU启动时&#xff0c;它会从闪存中读…

yolov8涨点系列之引入CBAM注意力机制

文章目录 YOLOv8 中添加注意力机制 CBAM 具有多方面的好处特征增强与选择通道注意力方面空间注意力方面 提高模型性能计算效率优化&#xff1a; yolov8增加CBAM具体步骤CBAM代码(1)在__init.pyconv.py文件的__all__内添加‘CBAM’(2)conv.py文件复制粘贴CBAM代码(3)修改task.py…

如何无缝更换WordPress主题:关键步骤详解

更换WordPress主题对于希望刷新网站外观或改善用户体验的站长来说&#xff0c;是一项常见但不容忽视的任务。无论是为了提升性能还是实现新的设计风格&#xff0c;在更换主题时&#xff0c;确保不遗漏任何重要细节至关重要。本文将详细介绍更换WordPress主题的关键步骤&#xf…

推荐一款PowerPoint转Flash工具:iSpring Suite

iSpring Suite是一款PowerPoint转Flash工具&#xff0c;使用iSpring Suite 8可以轻松的将PPT演示文档转换为对Web友好的Flash影片格式。软件界面简洁&#xff0c;使用方便。为什么要转换成flash格式呢?Flash格式的最大特点是体积小巧、易于分发&#xff0c;兼容所有的操作系统…

【案例】故障雪花屏

开发平台&#xff1a;Unity 6.0 开发工具&#xff1a;Shader Graph 参考视频&#xff1a;【U2D Shader Graph】❄️雪❄️花❄️屏❄️   一、效果图 二、Shader Graph 路线图 三、案例分析 核心思路&#xff1a;雪花屏幕效果 &#xff08;混合&#xff09; 原图像 最终图像…

ffplay 实现视频流中音频的延迟

ffplay -rtsp_transport tcp -i rtsp://admin:1234qwer192.168.1.64:554/Streaming/Channels/101 -vn -af "adelay5000|5000"在这个命令中&#xff1a; -vn 参数表示只播放音频。 -af "adelay5000|5000" 参数表示将音频延迟5000毫秒&#xff08;即5秒&…

科技资讯|谷歌Play应用商店有望支持 XR 头显,AR / VR设备有望得到发展

据 Android Authority 报道&#xff0c;谷歌似乎正在为其 Play 商店增加对 XR 头显的支持。该媒体在 Play 商店的代码中发现了相关的线索&#xff0c;包括一个代表头显的小图标以及对“XR 头显”的提及。 谷歌也可能改变了此前拒绝将 Play 商店引入 Meta Quest 头显的决定。今…

Pr 视频效果:超级键

视频效果/键控/超级键 Keying/Ultra Key 超级键 Ultra Key效果是 Premiere Pro 中功能强大的抠像工具&#xff0c;主要用于绿幕/蓝幕抠像。通过选择要抠除的颜色&#xff08;通常是绿幕或蓝幕的颜色&#xff09;&#xff0c;即可以将该颜色的像素设为透明&#xff0c;实现主体与…

Git使用指南

目录 工作机制基本框架:流程图 基本命令分支操作远程仓库本地仓库关联远程仓库 参考 工作机制 基本框架: Workspace&#xff1a;开发者工作区&#xff0c;也就是你当前写代码的目录&#xff0c;它一般保持的是最新仓库代码。Index / Stage&#xff1a;暂存区&#xff0c;最早…

计算机网络:简述LAN口模式下NAT和代理的区别

LAN口模式 NAT和代理的区别 LAN口模式下的NAT和代理的区别主要体现在定义、功能和应用场景上。 # NAT和代理的定义和功能 ‌NAT&#xff08;网络地址转换&#xff09;‌&#xff1a;NAT是一种网络地址翻译技术&#xff0c;它将内部私有IP地址转换为公网IP地址&#xff0c;使得…

qt QFile详解

1、概述 QFile类是Qt框架中用于读取和写入文本和二进制文件资源的I/O工具类。它继承自QFileDevice类&#xff0c;后者又继承自QIODevice类。QFile类提供了一个接口&#xff0c;允许开发者以二进制模式或文本模式对文件进行读写操作。默认情况下&#xff0c;QFile假定文件内容为…