为什么不显示我的 Jest 自定义匹配器的“消息”?
Why is the `message` for my Jest custom matcher not being displayed?
我创建了一个 Jest 自定义匹配器。它有效(意思是,它应该在 passes/fails 的时候),但我在 Jest 的输出中没有看到 message
。
我做错了什么?我必须做些什么来“启用”消息吗?我是不是完全误解了消息应该出现在哪里?
环境:NestJS、Prisma
执行命令:jest --watch
简化代码:
declare global {
namespace jest {
interface Matchers<R> {
toMatchHash(received: string, expected: string): R;
}
}
}
expect.extend({
toMatchJsonHash(received, expected) {
return {
pass: false,
message: () => `Why doesn't this work?!`,
};
},
});
expect(prisma.name.findMany).toHaveBeenCalledWith(expect.toMatchJsonHash('db0110285c148c77943f996a17cbaf27'));
输出:
● MyService › should pass a test using a custom matcher
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: toMatchJsonHash<db0110285c148c77943f996a17cbaf27>
Received: {<Big ol' object redacted for conciseness>}
Number of calls: 1
178 |
179 | // @ts-ignore
> 180 | expect(prisma.name.findMany).toHaveBeenCalledWith(expect.toMatchJsonHash('db0110285c148c77943f996a17cbaf27'));
| ^
181 | // expect(prisma.name.findMany).toHaveBeenCalledWith({
182 | // select: { type: true, name: true },
183 | // where: {
at Object.<anonymous> (my/my.service.spec.ts:180:32)
我期待看到“为什么这不起作用?!”在输出的某处,但我没有。我错过了什么?
作为 ,原因是 Jest 正在显示来自“外部”匹配器的消息,.toHaveBeenCalledWith()
。
为了解决这个问题,我找到了 the source that defines the .toHaveBeenCalledWith()
matcher 并将其代码“合并”到我的自定义匹配器中。
这使我的自定义匹配器能够有效地“扩展”.toHaveBeenCalledWith()
匹配器的功能,包括我自己的自定义代码和消息。
如果它对某人有帮助,我最终为我的特定用例编写的代码是:
declare global {
namespace jest {
interface Matchers<R> {
toHaveBeenCalledWithObjectMatchingHash(expected: string): CustomMatcherResult;
}
}
}
expect.extend({toHaveBeenCalledWithObjectMatchingHash(received, expected) {
const isSpy = (received: any) =>
received != null &&
received.calls != null &&
typeof received.calls.all === 'function' &&
typeof received.calls.count === 'function';
const receivedIsSpy = isSpy(received);
const receivedName = receivedIsSpy ? 'spy' : received.getMockName();
const calls = receivedIsSpy
? received.calls.all().map((x: any) => x.args)
: received.mock.calls;
if(calls.length === 0) {
return {
pass: false,
message: () => `expected the function to be called with an object that hashes to '${expected}'. Instead, the function was not called.`,
};
}
if(calls[0].length === 0) {
return {
pass: false,
message: () => `expected the function to be called with an object that hashes to '${expected}'. Instead, the function was called, but not with any arguments.`,
};
}
const md5Hash = crypto.createHash('md5');
const receivedHash = md5Hash.update(JSON.stringify(calls[0][0])).digest('hex');
const pass = receivedHash === expected;
if(pass) {
return {
pass: true,
message: () => `expected the function to not be called with an object that hashes to '${expected}'. Instead, the passed object hashes to the same value.`,
};
} else {
return {
pass: false,
message: () => `expected the function to be called with an object that hashes to '${expected}'. Instead, the passed object hashes to '${receivedHash}'.`,
};
}
}});
我创建了一个 Jest 自定义匹配器。它有效(意思是,它应该在 passes/fails 的时候),但我在 Jest 的输出中没有看到 message
。
我做错了什么?我必须做些什么来“启用”消息吗?我是不是完全误解了消息应该出现在哪里?
环境:NestJS、Prisma
执行命令:jest --watch
简化代码:
declare global {
namespace jest {
interface Matchers<R> {
toMatchHash(received: string, expected: string): R;
}
}
}
expect.extend({
toMatchJsonHash(received, expected) {
return {
pass: false,
message: () => `Why doesn't this work?!`,
};
},
});
expect(prisma.name.findMany).toHaveBeenCalledWith(expect.toMatchJsonHash('db0110285c148c77943f996a17cbaf27'));
输出:
● MyService › should pass a test using a custom matcher
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: toMatchJsonHash<db0110285c148c77943f996a17cbaf27>
Received: {<Big ol' object redacted for conciseness>}
Number of calls: 1
178 |
179 | // @ts-ignore
> 180 | expect(prisma.name.findMany).toHaveBeenCalledWith(expect.toMatchJsonHash('db0110285c148c77943f996a17cbaf27'));
| ^
181 | // expect(prisma.name.findMany).toHaveBeenCalledWith({
182 | // select: { type: true, name: true },
183 | // where: {
at Object.<anonymous> (my/my.service.spec.ts:180:32)
我期待看到“为什么这不起作用?!”在输出的某处,但我没有。我错过了什么?
作为 .toHaveBeenCalledWith()
。
为了解决这个问题,我找到了 the source that defines the .toHaveBeenCalledWith()
matcher 并将其代码“合并”到我的自定义匹配器中。
这使我的自定义匹配器能够有效地“扩展”.toHaveBeenCalledWith()
匹配器的功能,包括我自己的自定义代码和消息。
如果它对某人有帮助,我最终为我的特定用例编写的代码是:
declare global {
namespace jest {
interface Matchers<R> {
toHaveBeenCalledWithObjectMatchingHash(expected: string): CustomMatcherResult;
}
}
}
expect.extend({toHaveBeenCalledWithObjectMatchingHash(received, expected) {
const isSpy = (received: any) =>
received != null &&
received.calls != null &&
typeof received.calls.all === 'function' &&
typeof received.calls.count === 'function';
const receivedIsSpy = isSpy(received);
const receivedName = receivedIsSpy ? 'spy' : received.getMockName();
const calls = receivedIsSpy
? received.calls.all().map((x: any) => x.args)
: received.mock.calls;
if(calls.length === 0) {
return {
pass: false,
message: () => `expected the function to be called with an object that hashes to '${expected}'. Instead, the function was not called.`,
};
}
if(calls[0].length === 0) {
return {
pass: false,
message: () => `expected the function to be called with an object that hashes to '${expected}'. Instead, the function was called, but not with any arguments.`,
};
}
const md5Hash = crypto.createHash('md5');
const receivedHash = md5Hash.update(JSON.stringify(calls[0][0])).digest('hex');
const pass = receivedHash === expected;
if(pass) {
return {
pass: true,
message: () => `expected the function to not be called with an object that hashes to '${expected}'. Instead, the passed object hashes to the same value.`,
};
} else {
return {
pass: false,
message: () => `expected the function to be called with an object that hashes to '${expected}'. Instead, the passed object hashes to '${receivedHash}'.`,
};
}
}});