上一节我们学会了组件测试的基础测试部分组件测试基础篇,这一节,我们学习一下深入测试组件的事件
在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,第一章说过的
现在让我们增加一个测试项,来测试一下这个点击事件是否正常工作
运行测试代码,可以发现控制台能输出这个点击事件的打印信息,说明这个点击事件被调用了,当然我们这里并没有进行断言,所以这个例子只能证明点击事件是工作的,而不能证明它有什么用,我们还需要改造一下点击事件的内部逻辑,让它和标准组件那样暴露出一个emit来,然后我们去测试这个emit就能证明这个事件系统的作用了
接着我们改写一下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内置的一个工具,具体解释如下,我的理解是这个是函数的包装,
接着我们运行测试代码,查看测试结果,可以发现断言通过,并且控制台输出了wrapper包装器包含一个click事件源头
当然我们也可以写更多的事件去触发一下,查看一下控制台的输出情况,例如我们弄一个输入框组件来测试更多的事件例子,新增一个输入框组件
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;
});
});
最后执行一下测试代码,如果写了很多测试代码,只想测试某个文件怎么办呢?答案是利用过滤测试,在命令后面跟一个文件的名字即可,官网也有说明
测试运行结果如下,我的文件名字叫做input.test.tsx
好了这一章我们就学会了如何测试组件的事件,单纯测试事件并没有什么用处,这个应该结合Vue的双向绑定或者prop才有意义,那么下一章我们就测试一下prop