Expect
在编写测试时,通常需要检查值是否满足某些条件。expect
使您可以访问许多“匹配器”,以使您可以验证不同的内容。
有关Jest社区维护的其他Jest匹配器,请查看
方法
expect(value)
expect.extend(matchers)
expect.anything()
expect.any(constructor)
expect.arrayContaining(array)
expect.assertions(number)
expect.hasAssertions()
expect.not.arrayContaining(array)
expect.not.objectContaining(object)
expect.not.stringContaining(string)
expect.not.stringMatching(string | regexp)
expect.objectContaining(object)
expect.stringContaining(string)
expect.stringMatching(string | regexp)
expect.addSnapshotSerializer(serializer)
.not
.resolves
.rejects
.toBe(value)
.toHaveBeenCalled()
.toHaveBeenCalledTimes(number)
.toHaveBeenCalledWith(arg1, arg2, ...)
.toHaveBeenLastCalledWith(arg1, arg2, ...)
.toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....)
.toHaveReturned()
.toHaveReturnedTimes(number)
.toHaveReturnedWith(value)
.toHaveLastReturnedWith(value)
.toHaveNthReturnedWith(nthCall, value)
.toHaveLength(number)
.toHaveProperty(keyPath, value?)
.toBeCloseTo(number, numDigits?)
.toBeDefined()
.toBeFalsy()
.toBeGreaterThan(number | bigint)
.toBeGreaterThanOrEqual(number | bigint)
.toBeLessThan(number | bigint)
.toBeLessThanOrEqual(number | bigint)
.toBeInstanceOf(Class)
.toBeNull()
.toBeTruthy()
.toBeUndefined()
.toBeNaN()
.toContain(item)
.toContainEqual(item)
.toEqual(value)
.toMatch(regexpOrString)
.toMatchObject(object)
.toMatchSnapshot(propertyMatchers?, hint?)
.toMatchInlineSnapshot(propertyMatchers?, inlineSnapshot)
.toStrictEqual(value)
.toThrow(error?)
.toThrowErrorMatchingSnapshot(hint?)
.toThrowErrorMatchingInlineSnapshot(inlineSnapshot)
参考
expect(value)
expect
每次要测试一个值时都使用该函数。您很少会expect
自己打电话。取而代之的是,您将使用expect
“匹配器”功能来断言有关价值的某些事情。
通过示例更容易理解这一点。假设您有一个bestLaCroixFlavor()
应该返回string的方法'grapefruit'
。这是您将如何测试的方法:
test('the best flavor is grapefruit', () => {
expect(bestLaCroixFlavor()).toBe('grapefruit');
});
在这种情况下,toBe
是匹配器功能。有很多不同的匹配器功能,下面记录,以帮助您测试不同的事物。
的参数expect
应该是代码产生的值,匹配器的任何参数都应该是正确的值。如果将它们混合使用,您的测试仍然可以使用,但是关于失败的测试的错误消息看起来很奇怪。
expect.extend(matchers)
您可以expect.extend
用来将自己的匹配器添加到Jest。例如,假设您正在测试数字实用程序库,并且经常断言数字出现在其他数字的特定范围内。您可以将其抽象为toBeWithinRange
匹配器:
expect.extend({
toBeWithinRange(received, floor, ceiling) {
const pass = received >= floor && received <= ceiling;
if (pass) {
return {
message: () =>
`expected ${received} not to be within range ${floor} - ${ceiling}`,
pass: true,
};
} else {
return {
message: () =>
`expected ${received} to be within range ${floor} - ${ceiling}`,
pass: false,
};
}
},
});
test('numeric ranges', () => {
expect(100).toBeWithinRange(90, 110);
expect(101).not.toBeWithinRange(0, 100);
expect({
apples: 6, bananas: 3}).toEqual({
apples: expect.toBeWithinRange(1, 10),
bananas: expect.not.toBeWithinRange(11, 20),
});
});
注意:在TypeScript中,@types/jest
例如使用时,可以这样声明新的toBeWithinRange
匹配器:
declare global {
namespace jest {
interface Matchers<R> {
toBeWithinRange(a: number, b: number): R;
}
}
}
expect.extend
还支持异步匹配器。异步匹配器返回一个Promise,因此您需要等待返回的值。让我们使用示例匹配器来说明它们的用法。我们将实现一个名为的匹配器toBeDivisibleByExternalValue
,在该匹配器中,可从外部来源提取可除数。
expect.extend({
async toBeDivisibleByExternalValue(received) {
const externalValue = await getExternalValueFromRemoteSource();
const pass = received % externalValue == 0;
if (pass) {
return {
message: () =>
`expected ${received} not to be divisible by ${externalValue}`,
pass: true,
};
} else {
return {
message: () =>
`expected ${received} to be divisible by ${externalValue}`,
pass: false,
};
}
},
});
test('is divisible by external value', async () => {
await expect(100).toBeDivisibleByExternalValue();
await expect(101).not.toBeDivisibleByExternalValue();
});
匹配器应使用两个键返回一个对象(或对象的Promise)。pass
指示是否存在匹配项,并message
提供不带参数的函数,以防失败时返回错误消息。因此,when pass
为false时,message
应返回错误消息,为when expect(x).yourMatcher()
失败。而when pass
为true时,message
应返回when expect(x).not.yourMatcher()
失败的错误消息。
使用传递给的参数调用匹配器,expect(x)
然后传递给的参数.yourMatcher(y, z)
:
expect.extend({
yourMatcher(x, y, z) {
return {
pass: true,
message: () => '',
};
},
});
这些帮助器功能和属性可以this
在自定义匹配器中找到:
一个使您知道此匹配器的布尔值,它带有否定.not
修饰符,使您可以显示清晰正确的匹配器提示(请参见示例代码)。
一个字符串,可让您显示清晰正确的匹配提示:
'rejects'
如果使用promise.rejects
修饰符调用了matcher'resolves'
如果使用promise.resolves
修饰符调用了matcher''
如果未使用promise修饰符调用匹配器
这是一个深度相等函数,true
如果两个对象具有相同的值(递归),则将返回该函数。
一个布尔值,用于让您知道此匹配器是通过一个expand
选项调用的。当使用--expand
标志调用Jest时,this.expand
可用于确定是否期望Jest显示完整的差异和错误。
有很多有用的工具,this.utils
主要包括的出口jest-matcher-utils
。
最有用的是matcherHint
,printExpected
并printReceived
很好地格式化的错误消息。例如,看一下toBe
匹配器的实现:
const diff = require('jest-diff');
expect.extend({
toBe(received, expected) {
const options = {
comment: 'Object.is equality',
isNot: this.isNot,
promise: this.promise,
};
const pass = Object.is(received, expected);
const message = pass
? () =>
this.utils.matcherHint('toBe', undefined, undefined, options) +
'\n\n' +
`Expected: not ${
this.utils.printExpected(expected)}\n` +
`Received: