Props 与事件
基于 @vue/test-utils v2.x 编写
速查
- 传入:挂载选项
props/attrs - 更新:
await wrapper.setProps({ ... })(异步,必须 await) - 读取:
wrapper.props("key") - 事件:
wrapper.emitted("name")→[[arg1], [arg2], ...] - v-model:注册
"onUpdate:modelValue"回调 +setProps回写
传入 props
ts
const wrapper = mount(Password, {
props: { minLength: 10 },
});非 prop 的属性用 attrs:
ts
const wrapper = mount(Button, {
attrs: { disabled: true, "aria-label": "Submit" },
});更新 props
setProps 是异步的(要等 Vue 重渲染),必须 await:
ts
const wrapper = mount(Show, { props: { show: true } });
expect(wrapper.html()).toContain("Hello");
await wrapper.setProps({ show: false });
expect(wrapper.html()).not.toContain("Hello");断言自定义事件
emitted() 记录组件 emit 的所有事件,结构是 { 事件名: [[一次的参数...], ...] }:
ts
const wrapper = mount(Counter);
await wrapper.find("button").trigger("click");
await wrapper.find("button").trigger("click");
const events = wrapper.emitted("increment");
expect(events).toHaveLength(2); // emit 了两次
expect(events[0]).toEqual([1]); // 第 1 次的参数是 [1]
expect(events[1]).toEqual([2]); // 第 2 次的参数是 [2]ts
// 无参数事件:断言被触发
expect(wrapper.emitted("close")).toBeTruthy();
// 带 payload:取第 1 次触发的第 1 个参数
expect(wrapper.emitted("update")[0][0]).toEqual({ id: 1 });表单
ts
test("提交表单", async () => {
const wrapper = mount(Form);
await wrapper.find("input[type=email]").setValue("my@mail.com");
await wrapper.find("select").setValue("option-1");
await wrapper.find("input[type=checkbox]").setValue(); // 勾选
await wrapper.find("button").trigger("click");
expect(wrapper.emitted("submit")[0][0]).toBe("my@mail.com");
});测试 v-model
VTU 没有真实父组件,用注册 onUpdate:modelValue 回调 + setProps 回写来模拟双向绑定:
ts
test("v-model 双向绑定", async () => {
const wrapper = mount(Editor, {
props: {
modelValue: "initial",
"onUpdate:modelValue": (e) => wrapper.setProps({ modelValue: e }),
},
});
await wrapper.find("input").setValue("test");
expect(wrapper.props("modelValue")).toBe("test");
});多个 v-model 同理,为每个 onUpdate:xxx 注册回调:
ts
const wrapper = mount(CurrencyInput, {
props: {
modelValue: 0,
"onUpdate:modelValue": (e) => wrapper.setProps({ modelValue: e }),
currency: "USD",
"onUpdate:currency": (e) => wrapper.setProps({ currency: e }),
},
});