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.mzph.cn/web/58280.shtml

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

相关文章

省级-社会保障水平数据(2007-2022年)

社会保障水平是一个综合性的概念&#xff0c;它不仅涉及到一个国家或地区的社会保障制度覆盖范围&#xff0c;还包括了提供的保障种类与水平&#xff0c;以及这些制度在满足公民基本生活需求方面的能力。 2007-2022年省级-社会保障水平数据.zip资源-CSDN文库https://download.…

【毫米波雷达(三)】汽车控制器启动流程——BootLoader

汽车控制器启动流程——BootLoader 一、什么是Bootloader(BT)&#xff1f;二、FBL、PBL、SBL、ESS的区别三、MCU的 A/B分区的实现 一、什么是Bootloader(BT)&#xff1f; BT就是一段程序&#xff0c;一段引导程序。它包含了启动代码、中断、主程序等。 雷达启动需要由BT跳转到…

计算机网络——网络层导论

转发是局部功能——数据平面 路由是全局的功能——控制平面 网卡 网卡&#xff0c;也称为网络适配器&#xff0c;是计算机硬件中的一种设备&#xff0c;主要负责在计算机和网络之间进行数据传输。 一、主要功能 1、数据传输&#xff1a; 发送数据时&#xff0c;网卡将计算机…

使用 Python 调用云 API 实现批量共享自定义镜像

本文介绍如何通过 Python SDK 调用 API 接口&#xff0c;通过子用户批量共享云服务器自定义镜像。若您具备类似需求&#xff0c;或想了解如何使用 SDK&#xff0c;可参考本文进行操作。 前提条件 已创建子用户&#xff0c;并已具备云服务器及云 API 所有权限。 创建子用户请…

[mysql]修改表和课后练习

目录 DDL数据定义语言 添加一个字段 添加一个字段到最后一个 添加到表中的第一个一个字段 选择其中一个位置: 修改一个字段:数据类型,长度,默认值(略) 重命名一个字段 删除一个字段 重命名表 删除表 清空表 DCL中事务相关内容 DCL中COMMIT和ROLLBACK的讲解 对比TR…

Python异常检测 - LSTM(长短期记忆网络)

系列文章目录 Python异常检测- Isolation Forest&#xff08;孤立森林&#xff09; python异常检测 - 随机离群选择Stochastic Outlier Selection (SOS) python异常检测-局部异常因子&#xff08;LOF&#xff09;算法 Python异常检测- DBSCAN Python异常检测- 单类支持向量机(…

常见Transformer位置编码

文章目录 概述绝对位置编码相对位置编码T5 BiasALiBiRoPE 参考资料 概述 相对于RNN这样的序列模型来说&#xff0c;Transformer可并行是一个很大的优势&#xff0c;但可并行性带来一个问题&#xff0c;由于不是从前到后&#xff0c;所以模型对于位置信息是不敏感的。于是在Tra…

【IEEE出版 | EI稳定检索】2024智能机器人与自动控制国际学术会议 (IRAC 2024,11月29-12月1日)

2024智能机器人与自动控制国际学术会议 &#xff08;IRAC 2024&#xff09; 2024 International Conference on Intelligent Robotics and Automatic Control 官方信息 会议官网&#xff1a;www.icirac.org 2024 International Conference on Intelligent Robotics and Autom…

Golang | Leetcode Golang题解之第535题TinyURL的加密与解密

题目&#xff1a; 题解&#xff1a; import "math/rand"type Codec map[int]stringfunc Constructor() Codec {return Codec{} }func (c Codec) encode(longUrl string) string {for {key : rand.Int()if c[key] "" {c[key] longUrlreturn "http:/…

影响神经网络速度的因素- FLOPs、MAC、并行度以及计算平台

影响神经网络速度的四个主要因素分别是 FLOPs&#xff08;浮点操作数&#xff09;、MAC&#xff08;内存访问成本&#xff09;、并行度以及计算平台。这些因素共同作用&#xff0c;直接影响到神经网络的计算速度和资源需求。 1. FLOPs&#xff08;Floating Point Operations&a…

【北京迅为】《STM32MP157开发板嵌入式开发指南》-第七十六章 C++入门

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

小菜家教平台:基于SpringBoot+Vue打造一站式学习管理系统

前言 现在已经学习了很多与Java相关的知识&#xff0c;但是迟迟没有进行一个完整的实践&#xff08;之前这个项目开发到一半&#xff0c;很多东西没学搁置了&#xff0c;同时原先的项目中也有很多的问题&#xff09;&#xff0c;所以现在准备从零开始做一个基于SpringBootVue的…

基于Matlab的语音识别

一、引言 语音识别技术是让计算机识别一些语音信号&#xff0c;并把语音信号转换成相应的文本或者命令的一种高科技技术。语音识别技术所涉及的领域非常广泛&#xff0c;包括信号处理、模式识别、人工智能等技术。近年来已经从实验室开始走向市场&#xff0c;渗透到家电、通信…

如何在 IntelliJ IDEA 中调整 `Ctrl+/` 快捷键生成注释的位置

前言 在使用 IntelliJ IDEA 编写代码时&#xff0c;注释是代码可读性和维护性的重要组成部分。IDEA 提供了快捷键 Ctrl/ 用于快速生成单行注释。然而&#xff0c;默认情况下&#xff0c;使用此快捷键生成的注释会出现在行首&#xff0c;导致注释与代码之间存在较大的空格&…

源鲁杯 2024 web(部分)

[Round 1] Disal F12查看: f1ag_is_here.php 又F12可以发现图片提到了robots 访问robots.txt 得到flag.php<?php show_source(__FILE__); include("flag_is_so_beautiful.php"); $a$_POST[a]; $keypreg_match(/[a-zA-Z]{6}/,$a); $b$_REQUEST[b];if($a>99999…

使用 ADB 在某个特定时间点点击 Android 设备上的某个按钮

前提条件 安装 ADB&#xff1a;确保你已经在计算机上安装了 Android SDK&#xff08;或单独的 ADB&#xff09;。并将其添加到系统环境变量中&#xff0c;以便你可以在命令行中运行 adb。 USB调试&#xff1a;确保 Android 设备已启用 USB 调试模式。这可以在设备的“设置” -…

数据库的使用02:SQLServer的连接字符串、备份、还原、SQL监视相关设置

目录 一、连接字符串 【本地连接字符串】 【远程连接字符串】 二、备份 三、还原 &#xff08;1&#xff09;还原数据库-bak、btn文件 &#xff08;2&#xff09;附加数据库mdf文件 四、SQL监视器的使用 一、连接字符串 【本地连接字符串】 server DESKTOP-FTH2P3S; Da…

Oracle视频基础1.3.6练习

1.3.6 以下是您的需求清单&#xff08;不含解决方案&#xff09;&#xff1a; 检查数据库启动情况等待会话结束&#xff0c;进行正常关机等待事务全部提交后再关机查看 alert 日志文件查看后台跟踪文件查看用户跟踪文件 检查数据库启动情况 ps -ef | grep oracle ipcs clear…

【大数据学习 | HBASE】hbase的原理与组成结构

1. hbase的简述 hbase作为google的大数据三篇比较重要的论文之一&#xff0c;它的起源叫做bigtable&#xff0c;意思非常简单就是大表的意思&#xff0c;是一个分布式存储很多数据的大型表格系统&#xff0c;它是对于hdfs中的数据不能直观查询和随机读写的病痛的一个补充和完善…

苍穹外卖Bug集合

初始化后端项目运行出现以下问题 以上报错是因为maven和jdk版本不符合&#xff0c;需要将jdk改成17&#xff0c;mavne改成3.9.9