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单元测试环境+组件事件测试篇_第1张图片

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

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

接着我们改写一下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单元测试环境+组件事件测试篇_第4张图片
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇_第5张图片
接着我们运行测试代码,查看测试结果,可以发现断言通过,并且控制台输出了wrapper包装器包含一个click事件源头
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇_第6张图片

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

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 () => (
      <input
        placeholder="请输入"
        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(() => (
      <ZmInput
        onBlur={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单元测试环境+组件事件测试篇_第7张图片
测试运行结果如下,我的文件名字叫做input.test.tsx
Vue3+Typescript+Vitest单元测试环境+组件事件测试篇_第8张图片

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

你可能感兴趣的:(单元测试,vue3,typescript,单元测试)