1. 什么是匹配器?
使用不同匹配器可以测试输入输出的值是否符合预期。
例如:下面的 toBe、toBeGreaterThan 都是匹配器。
test('two plus two is four', () => {
expect(2 + 2).toBe(4);
expect(2 + 2).toBeGreaterThan(3);
});
2. 普通匹配
2.1. toBe(value)
Use .toBe to compare primitive values or to check referential identity of object instances. It calls Object.is to compare values, which is even better for testing than === strict equality operator.
注意:Don't use .toBe with floating-point numbers.
const can = {
name: 'pamplemousse',
ounces: 12,
};
describe('the can', () => {
test('has 12 ounces', () => {
expect(can.ounces).toBe(12);
});
test('has a sophisticated name', () => {
expect(can.name).toBe('pamplemousse');
});
});
2.2. toBeNull()、toBeUndefined()、toBeDefined()
.toBeNull() is the same as .toBe(null)
test('null-defined', () => {
expect(null).toBeNull();
expect(undefined).not.toBeNull();
expect(undefined).toBeUndefined();
expect(null).not.toBeUndefined();
expect(null).toBeDefined();
});
2.3. toBeNaN()
Use .toBeNaN when checking a value is NaN.
test('passes when value is NaN', () => {
expect(NaN).toBeNaN();
expect(1).not.toBeNaN();
});
2.4. toBeTruthy()、toBeFalsy()
test('toBeTruthy-toBeFalsy', () => {
expect(1).toBeTruthy();
expect("a").toBeTruthy();
expect({}).toBeTruthy();
expect([]).toBeTruthy();
expect(true).toBeTruthy();
expect("false").toBeTruthy();
expect("").toBeFalsy();
expect(0).toBeFalsy();
expect(false).toBeFalsy();
expect(NaN).toBeFalsy();
});
3. 字符串匹配
3.1. toMatch(regexpOrString)
Use .toMatch to check that a string matches a regular expression.
test('there is no I in team', () => {
expect('team').not.toMatch(/in team$/);
});
test('but there is a "stop" in Christoph', () => {
expect('Christoph').toMatch(/stop/);
});
4. 数值匹配
test('number', () => {
expect(10).toBeGreaterThan(5);
expect(10).toBeGreaterThanOrEqual(10);
expect(10).toBeLessThan(20);
expect(10).toBeLessThanOrEqual(10);
expect(0.1 + 0.2).toBeCloseTo(0.3);
expect(0.1 + 0.2).not.toBe(0.3); // 特别注意
});
5. 数组匹配
5.1. toContain(item)
Use .toContain when you want to check that an item is in an array. For testing the items in the array, this uses ===, a strict equality check. .toContain can also check whether a string is a substring of another string.
test('', () => {
expect(["lime", "abc", "bcd"]).toContain('lime');
});
5.2. toHaveLength(number)
Use .toHaveLength to check that an object has a .length property and it is set to a certain numeric value.
test('', () => {
expect([1, 2, 3]).toHaveLength(3);
expect('abc').toHaveLength(3);
});
6. 对象匹配
6.1. toBeInstanceOf(Class)
Use .toBeInstanceOf(Class) to check that an object is an instance of a class.
test('', () => {
class A {}
expect(new A()).toBeInstanceOf(A);
expect(() => {}).toBeInstanceOf(Function);
expect(new A()).toBeInstanceOf(Object); // throws
});
6.2. toEqual(value)
Use .toEqual to compare recursively all properties of object instances (also known as "deep" equality). It calls Object.is to compare primitive values.
test('', () => {
expect({
flavor: 'grapefruit',
ounces: 12,
}).toEqual({
flavor: 'grapefruit',
ounces: 12,
});
expect([1, 2, 3]).not.toBe([1, 2, 3]);
expect([1, 2, {
flavor: 'grapefruit',
ounces: 12,
}]).not.toBe([1, 2, {
flavor: 'grapefruit',
ounces: 12,
}]);
});
6.3. toHaveProperty(keyPath, value?)
Use .toHaveProperty to check if property at provided reference keyPath exists for an object.
value
argument to compare the received property value (recursively for all properties of object instances, also known as deep equality, like the toEqual
matcher).
// Object containing house features to be tested
const houseForSale = {
bath: true,
bedrooms: 4,
kitchen: {
amenities: ['oven', 'stove', 'washer'],
area: 20,
wallColor: 'white',
'nice.oven': true,
},
'ceiling.height': 2,
};
test('this house has my desired features', () => {
// Example Referencing
expect(houseForSale).toHaveProperty('bath');
expect(houseForSale).toHaveProperty('bedrooms', 4);
expect(houseForSale).not.toHaveProperty('pool');
// Deep referencing using dot notation
expect(houseForSale).toHaveProperty('kitchen.area', 20);
expect(houseForSale).toHaveProperty('kitchen.amenities', [
'oven',
'stove',
'washer',
]);
expect(houseForSale).not.toHaveProperty('kitchen.open');
// Deep referencing using an array containing the keyPath
expect(houseForSale).toHaveProperty(['kitchen', 'area'], 20);
expect(houseForSale).toHaveProperty(
['kitchen', 'amenities'],
['oven', 'stove', 'washer'],
);
expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven');
expect(houseForSale).toHaveProperty(['kitchen', 'nice.oven']);
expect(houseForSale).not.toHaveProperty(['kitchen', 'open']);
// Referencing keys with dot in the key itself
expect(houseForSale).toHaveProperty(['ceiling.height'], 2);
});
6.4. toMatchObject(object)
Use .toMatchObject to check that a JavaScript object matches a subset of the properties of an object. It will match received objects with properties that are not in the expected object.
const houseForSale = {
bath: true,
bedrooms: 4,
kitchen: {
amenities: ['oven', 'stove', 'washer'],
area: 20,
wallColor: 'white',
},
};
const desiredHouse = {
bath: true,
kitchen: {
amenities: ['oven', 'stove', 'washer'],
wallColor: expect.stringMatching(/white|yellow/),
},
};
test('the house has my desired features', () => {
expect(houseForSale).toMatchObject(desiredHouse);
});
test('the number of elements must match exactly', () => {
expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}, {baz: 1}]);
});
test('.toMatchObject is called for each elements, so extra object properties are okay', () => {
expect([{foo: 'bar'}, {baz: 1, extra: 'quux'}]).toMatchObject([
{foo: 'bar'},
{baz: 1},
]);
});
6.5. toStrictEqual(value)
Use .toStrictEqual to test that objects have the same types as well as structure.
class LaCroix {
constructor(flavor) {
this.flavor = flavor;
}
}
test('are not semantically the same', () => {
expect(new LaCroix('lemon')).toEqual({flavor: 'lemon'});
expect(new LaCroix('lemon')).not.toStrictEqual({flavor: 'lemon'});
});
7. 异常匹配
7.1. toThrow(error?)
Use .toThrow to test that a function throws when it is called.
function myfn(){
console.log(X);
}
test('throws on octopus', () => {
expect(() => {
myfn();
}).toThrow();
});