“ . toMatchObject”和“ object  包含”有什麼不同

我写了以下的测试:

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 }));
});

他们似乎都通过了测试,他们之间有什么区别吗?它们之间是否存在性能影响?

77026 次浏览

我的想法是,可以使用 expect.objectContaining(和其他配偶喜欢它)来代替传递给其他匹配器的“对象”中的文字值。

这个例子来自文档:

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),
}));
});

因此,虽然在您的示例中它们似乎做了同样的事情,但是 expect.*在其他方面也很有用。

From looking at the docs, and my own experimentation to confirm it, the difference is in the handling of objects nested within the props passed as an expectation.

如果期望对象有一个包含对象的属性,该属性包含实际对象的等价属性中的属性的 有些但不是全部,那么:

  • 仍将通过 .toMatchObject()从文件中可以看出

  • expect.objectContaining()将失败(除非您使用 expect.objectContaining()在期望对象本身中声明该属性)

例子(在玩笑中测试) :

  // 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)
}
});

即使这两种结构之间没有功能上的差异,下面的例子也可以解释为什么 expect.objectContaining——尽管与 toMatchObject相比冗长而笨重——可以是有用的:

describe('list of X', () => {
it('should contain an element with a specific ID', () => {
const listOfItems = uut.getItems();
expect(listOfItems).toContainEqual(expect.objectContaining({id: 'some-id'}));
});
});

即使 listOfItems包含这样的项(即,除了‘ id’之外还包含其他字段)——

[
{id: 'some-id', other: 'fields'},
{id: 'some-other-id', even: 'more-fields'}
]

但是 expect.objectContaining仍然允许像您期望的那样实现比较的简单方法(即严格基于 id) ; toMatchObject根本不能在这里使用。因此,虽然 toMatchObject短小精悍,可读性强,但是两者的较长结构更具通用性,并且允许更大的灵活性,因为它可以以 toMatchObject()无法利用的方式加以利用。