javascript - Sự khác nhau giữa '.toMatchObject' và 'objectContaining' là gì
Tôi đã viết bài kiểm tra sau:
it('Can decrement the current step', function () {
expect(reducer(TestState, { type: 'GOTO_PREVIOUS_STEP' })).toMatchObject({ currentStep: 4 });
});
it('Can decrement the current step v2', function () {
expect(reducer(TestState, { type: 'GOTO_PREVIOUS_STEP' })).toEqual(expect.objectContaining({ currentStep: 4 }));
});
cả hai dường như đều vượt qua bài kiểm tra, có sự khác biệt nào giữa chúng không? có ảnh hưởng gì về hiệu suất giữa chúng không?
Câu trả lời #1
Qua việc xem tài liệu và tự mình thử nghiệm để xác nhận, sự khác biệt nằm ở cách xử lý các đối tượng lồng nhau bên trong các props được truyền như một kỳ vọng.
Nếu đối tượng kỳ vọng có một thuộc tính, chứa một đối tượng, mà chứa một số nhưng không phải tất cả các thuộc tính trong thuộc tính tương ứng của đối tượng thực tế, thì:
.toMatchObject()vẫn sẽ thành công, như đã thấy trong tài liệu.expect.objectContaining()sẽ thất bại (trừ khi bạn khai báo thuộc tính đó trong chính đối tượng mong đợi vớiexpect.objectContaining())
Ví dụ (đã kiểm thử trong Jest):
// objectContaining, with nested object, containing full props/values
// PASSES
expect({ position: { x: 0, y: 0 } }).toEqual(expect.objectContaining({
position: {
x: expect.any(Number),
y: expect.any(Number)
}
}));
// objectContaining, with nested object, containing partial props/values
// FAILS
expect({ position: { x: 0, y: 0 } }).toEqual(expect.objectContaining({
position: {
x: expect.any(Number)
}
}));
// objectContaining, with nested object, also declared with objectContaining, containing partial props/values
// PASSES
expect({ position: { x: 0, y: 0 } }).toEqual(expect.objectContaining({
position: expect.objectContaining({
x: expect.any(Number)
})
}));
// toMatchObject, with nested object, containing full props/values
// PASSES
expect({ position: { x: 0, y: 0 } }).toMatchObject({
position: {
x: expect.any(Number),
y: expect.any(Number)
}
});
// toMatchObject, with nested object, containing partial props/values
// PASSES
expect({ position: { x: 0, y: 0 } }).toMatchObject({
position: {
x: expect.any(Number)
}
});
Câu trả lời #2
Suy nghĩ của tôi là expect.objectContaining (và các matcher khác tương tự) có thể được sử dụng thay cho các giá trị cụ thể bên trong "object" mà bạn truyền cho các matcher khác.
Ví dụ này từ tài liệu:
test('onPress gets called with the right thing', () => {
const onPress = jest.fn();
simulatePresses(onPress);
expect(onPress).toBeCalledWith(expect.objectContaining({
x: expect.any(Number),
y: expect.any(Number),
}));
});
Vì vậy, mặc dù chúng có vẻ làm cùng một việc trong ví dụ của bạn, các expect.* cũng hữu ích theo cách khác này.
