Javascript “.toMatchObject”和“objectContaining”有什么区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45692456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between '.toMatchObject' and 'objectContaining'
提问by Julito Sanchis
I have written the following test:
我编写了以下测试:
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 }));
});
both of them seem to pass the test, is there any difference between them? is there a performance impact between them?
他们两个好像都通过了测试,他们之间有什么区别吗?它们之间有性能影响吗?
回答by Jonathan
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.
从查看文档和我自己的实验来确认,不同之处在于对嵌套在作为期望传递的道具中的对象的处理。
If the expectation object has a property, containing an object, which contains some but not allof the properties in the equivalent property of the actual object, then:
如果期望对象有一个属性,包含一个对象,该对象包含实际对象的等效属性中的部分但不是全部属性,则:
toMatchObject will still pass, as seen in the docs.
expect.objectContaining will fail (unless you declare that property in the expectation object itself with expect.objectContaining())
toMatchObject 仍会通过,如文档中所示。
expect.objectContaining 将失败(除非您使用 expect.objectContaining() 在期望对象本身中声明该属性)
Examples (tested in Jest):
示例(在 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)
}
});
回答by David
My thinking is that expect.objectContaining (and other matchers like it) can be used instead of literal values inside the "object" you pass to other matchers.
我的想法是可以使用 expect.objectContaining (以及其他类似的匹配器)代替传递给其他匹配器的“对象”中的文字值。
This example is from the docs:
这个例子来自文档:
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),
}));
});
So, while they seem to do the same thing in your example, the expect.* ones are also useful in this other way.
所以,虽然他们在你的例子中似乎做同样的事情,但 expect.* 的在这方面也很有用。
回答by d4vidi
Even without functional differences between the two constructs, here's an example as to why expect.objectContaining- though long and cumbersome compared to toMatchObject, can be useful:
即使这两种结构之间没有功能差异,以下是一个解释原因的示例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'}));
});
});
Even if listOfItemscontains items as such (i.e. with fields other than just the 'id') --
即使listOfItems包含这样的项目(即除了“id”之外的字段)-
[
{id: 'some-id', other: 'fields'},
{id: 'some-other-id', even: 'more-fields'}
]
still expect.objectContainingallows for a simple way of implementing the comparison as you'd expect (i.e. based strictly on the id); toMatchObjectcannot be used here at all. So while toMatchObjectis short and readable, the longer construct of the two is more generic and allows for greater flexibility as it can be utilized in ways that toMatchObject()can't.
仍然expect.objectContaining允许使用一种简单的方法来实现您所期望的比较(即严格基于 id);toMatchObject根本不能在这里使用。因此,虽然toMatchObject简短易读,但两者中较长的结构更通用,并允许更大的灵活性,因为它可以以不能使用的方式使用toMatchObject()。

