> 文章列表 > Vue3+Typescript+Vitest单元测试环境+组件事件测试篇

Vue3+Typescript+Vitest单元测试环境+组件事件测试篇

Vue3+Typescript+Vitest单元测试环境+组件事件测试篇

上一节我们学会了组件测试的基础测试部分组件测试基础篇,这一节,我们学习一下深入测试组件的事件

在component中增加一个新的组件,名字就叫做Zmbutton2吧

import { defineComponent } from "vue";const ZmButton2 = defineComponent({name: "ZmButton2",setup() {const clickHandler = (e: Event) => {console.log("当前组件的点击事件参数是:", e);};return () => <button onClick={clickHandler}>测试事件</button>;},
});
export default ZmButton2;

在对应的测试文件中新增测试代码如下,先断言这个组件的正确渲染,看代码行数旁边的图标,是测试通过的,这个是vscdoe的插件,vitest,第一章说过的
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇

现在让我们增加一个测试项,来测试一下这个点击事件是否正常工作

Vue3+Typescript+Vitest单元测试环境+组件事件测试篇
运行测试代码,可以发现控制台能输出这个点击事件的打印信息,说明这个点击事件被调用了,当然我们这里并没有进行断言,所以这个例子只能证明点击事件是工作的,而不能证明它有什么用,我们还需要改造一下点击事件的内部逻辑,让它和标准组件那样暴露出一个emit来,然后我们去测试这个emit就能证明这个事件系统的作用了
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇

接着我们改写一下ZmButton2的组件设计

现在我们让组件内部暴露了一个emit事件,那么在外面我们就能断言这个事件是否被调用,从而简介测试了组件内部的某些事件是否正常工作

import { defineComponent } from "vue";const ZmButton2 = defineComponent({name: "ZmButton2",emits: ["click"],setup(props, { emit }) {const clickHandler = (e: Event) => {emit("click", e);};return () => <button onClick={clickHandler}>测试事件</button>;},
});
export default ZmButton2;

现在增加一个测试项,用来测试事件emit

看注释内容,这里需要掌握一些前置知识,其中vi.fn是vitest内置的一个工具,具体解释如下,我的理解是这个是函数的包装,
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇
接着我们运行测试代码,查看测试结果,可以发现断言通过,并且控制台输出了wrapper包装器包含一个click事件源头
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇

当然我们也可以写更多的事件去触发一下,查看一下控制台的输出情况,例如我们弄一个输入框组件来测试更多的事件例子,新增一个输入框组件

import { defineComponent } from "vue";const ZmInput = defineComponent({name: "ZmInput",emits: ["focus", "blur", "change", "input"],setup(props, { emit }) {// 聚焦事件const focusHandler = () => {emit("focus");};// 失去焦点事件const blurHandler = () => {emit("blur");};// change事件const changeHandler = () => {emit("change");};// 输入事件const inputHandler = () => {emit("input");};return () => (<inputplaceholder="请输入"onChange={changeHandler}onFocus={focusHandler}onBlur={blurHandler}onInput={inputHandler}/>);},
});export default ZmInput;

在对应组件的测试文件中写入一下内容测试这些事件测试

import { mount } from "@vue/test-utils";
import { describe, expect, it, vi } from "vitest";
import ZmInput from "../input";
import { nextTick } from "vue";describe("input", () => {// 按照惯例测试是否正常渲染it("render", () => {const wrapper = mount(() => <ZmInput />);expect(wrapper.exists()).toBeTruthy();});// 接着一口气测试所有的事件源头,正常的测试应该是单一的,一个一个单独事件测试,但是这里演示就一起写了it("events test", async () => {const focusHandler = () => {console.log("got focus");};const changeHandler = () => {console.log("change");};const blurHandler = () => {console.log("blur");};const inputHandler = () => {console.log("inputHandler");};const wrapper = mount(() => (<ZmInputonBlur={blurHandler}onChange={changeHandler}onFocus={focusHandler}onInput={inputHandler}/>));// 先聚焦wrapper.trigger("focus");// 失去焦点wrapper.trigger("blur");// 触发change事件wrapper.trigger("change");// 触发input事件,这种事件也可以被value值改变时触发wrapper.trigger("input");await nextTick();expect(focusHandler).toHaveBeenCalled;expect(changeHandler).toHaveBeenCalled;expect(blurHandler).toHaveBeenCalled;expect(inputHandler).toHaveBeenCalled;});
});

最后执行一下测试代码,如果写了很多测试代码,只想测试某个文件怎么办呢?答案是利用过滤测试,在命令后面跟一个文件的名字即可,官网也有说明
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇
测试运行结果如下,我的文件名字叫做input.test.tsx
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇

好了这一章我们就学会了如何测试组件的事件,单纯测试事件并没有什么用处,这个应该结合Vue的双向绑定或者prop才有意义,那么下一章我们就测试一下prop