如何让 Jest 自定义匹配器在打字稿中工作?
Posted
技术标签:
【中文标题】如何让 Jest 自定义匹配器在打字稿中工作?【英文标题】:How to get a Jest custom matcher working in typescript? 【发布时间】:2020-05-30 07:38:31 【问题描述】:我经常进行单元测试,我需要比较两个矩对象。我要我们 moment 的内置函数 moment.isSame(moment) 来比较它们。但是,这意味着我的断言将如下所示:
expect(moment1.isSame(moment2)).toBeTrue();
我不太喜欢这样,尤其是因为失败消息的信息量较少。因此,我想编写一个自定义的笑话匹配器“toBeSameMoment”。以下代码似乎至少可以编译:
import moment from "moment";
declare global
namespace jest
interface MomentMatchers extends Matchers<moment.Moment>
toBeSameMoment: (expected: moment.Moment) => CustomMatcherResult;
expect.extend(
toBeSameMoment(received: moment.Moment, expected: moment.Moment): jest.CustomMatcherResult
const pass: boolean = received.isSame(expected);
const message: () => string = () => pass ? "" : `Received moment ($received.toISOString()) is not the same as expected ($expected.toISOString())`;
return
message,
pass,
;
,
);
但是,我真的不能让它在我的单元测试中工作...... 当我尝试以下测试代码时:
import moment from "moment";
import "../jest-matchers/moment";
describe("Moment matcher", () =>
test("should fail", () =>
const moment1 = moment.utc();
const moment2 = moment();
expect(moment1).toBeSameMoment(moment2);
);
);
...然后我收到以下错误:
error TS2339: Property 'toBeSameMoment' does not exist on type 'JestMatchersShape<Matchers<void, Moment>, Matchers<Promise<void>, Moment>>'.
不过,我不太明白这个错误。例如,这里指的 void 类型是什么?我试过用谷歌搜索它,但并没有真正找到一个好的指南。我确实注意到了这个问题:How to let know typescript compiler about jest custom matchers?,这似乎基本上是重复的,但显然还不够清楚。
我的 tsconfig 中包含 jest 类型
【问题讨论】:
【参考方案1】:您链接到的另一个问题和答案是正确的,您还可以在 react-testing-library 上的this github comment 中找到一个非常简洁的示例来说明如何扩展 jest。
要为您的代码实施他们的解决方案,只需更改:
declare global
namespace jest
interface MomentMatchers extends Matchers<moment.Moment>
toBeSameMoment: (expected: moment.Moment) => CustomMatcherResult;
收件人:
declare global
namespace jest
interface Matchers<R>
toBeSameMoment(expected: moment.Moment): CustomMatcherResult;
【讨论】:
确实,这行得通。谢谢!你能解释一下这个“R”指的是什么吗?<_>
表示 TypeScript 中的泛型,它基本上是要由其他代码填充的类型的占位符。在这个特定的场景中,我猜他们使用R
代表Received,这是有道理的,因为如果你查看@types/jest/index.d.ts
,你可以看到他们也使用<E>
在 Matchers 上定义的方法中,其中E
是预期值的类型。
好吧,这对我来说开始有些意义了......我有点期望我需要自己提供类型参数,但如果 R 意味着收到,那就解释了。期望参数的类型需要是相同的类型,因此类型可以从expect方法接收到的对象中推断出来。
在 Typescript v4 中 @typescript-eslint/no-namespace 失败并显示 ES2015 module syntax is preferred over custom TypeScript modules and namespaces
。有没有比简单地禁用此规则更好的方法?或者只要jest
是全局的,就必须禁用?
你把 jest.d.ts 放在哪里让这个解决方案真正起作用?以上是关于如何让 Jest 自定义匹配器在打字稿中工作?的主要内容,如果未能解决你的问题,请参考以下文章
如何让 CSS 选择器在 Chrome 17 的开发者工具中工作?
带有 Jest 的打字稿 - “ReferenceError:未定义 beforeAll”