我正在用jest测试一些Vue 3组件,并期望在单击按钮时获得一个emit。现在我想检查所发出的对象是否与我在另一个文件中创建的自定义类型匹配。例如:
//types.ts
export type customType = {
foo: string;
bar: {
foobar: number;
barfoo: number;
};
}
我的测试用例看起来像这样:
//Component.spec.js
it("tests if types match", () => {
const wrapper = [...];
// do some stuff to get this event emitted
expect(typeof wrapper.emitted().customEvent).toBe(customType);
});
但这里我得到的错误是Element is not accessible
atcustomType
尽管我导入了它
如何检查自定义事件发出的变量是否与自定义类型匹配?
你看到这个的原因是因为Jest的expect
不是类型感知的,因为测试是在运行时编译成JavaScript的。
有两种可能的方法:
。如果您真的想在编译时评估自定义类型,请使用expect-type package
import { expectTypeOf } from 'expect-type'
expectTypeOf(wrapper.emitted().customEvent).toEqualTypeOf<customType>()
在底层,它仍然使用JavaScript,类似于B.2。下面,除了您不需要自己编写函数之外,它是从提供的类型动态生成的。
注意toMatchTypeOf
和toEqualTypeOf
之间的差异(后者更严格-例如:在额外的道具上失败)
B。坚持使用JavaScript,使用以下选项:
责任。最简单的解决方案是检查实际值:
expect(wrapper.emitted().customEvent).toEqual(someValue)
// I'm guessing you know the value in the test
B.2。或者,您可以创建一个函数,将该值作为参数,并检查您的类型的所有必需的props。例句:
const checkCustomEvent = event =>
typeof event?.foo === 'string' &&
[event?.bar?.barfoo, event?.bar?.foobar]
.every(el => typeof el === 'number');
expect(checkCustomEvent(wrapper.emitted().customEvent)).toBe(true)
B.3。另一种选择(我个人不喜欢它,很少使用它)是将您的customType更改为一个类。此时,您可以检查:
expect(wrapper.emitted().customEvent instanceof SomeClass).toBe(true)
// or
expect(wrapper.emitted().customEvent).toBeInstanceOf(SomeClass)
我个人更喜欢第一个js方法(B.1.)。如果我有动态的结果,并且写一个类型保护函数来检查它们是有意义的,我可能会这样做(B.2.)。
旁注:我怀疑emitted()[someKey]
的值永远不会成为对象。根据文档,它将是一个数组的数组:Array<Array<any>>
。您可能想使用wrapper.emitted().customEvent[0][0]
,而不是wrapper.emitted().customEvent