Jest文档如下:
toBe只是检查一个值是否是你所期望的。它使用===来检查严格相等。
对于toEqual
:
如果要检查两个对象是否具有相同的值,请使用.toEqual。这个匹配器递归地检查所有字段的相等性,而不是检查对象的身份-这也被称为“深度相等”。例如,toEqual和toBe在这个测试套件中的行为不同,因此所有测试都通过。
const x = { a: { b: 3 } };
const y = { a: { b: 3 } };
expect(x).toEqual(y);
expect(x).toBe(y);
在这种情况下,toEqual
通过,但toBe
失败。我理解toEqual
通过是因为它做了一个 deep equal 检查。为什么toBe
在这种情况下会失败?
另外,是否有使用toBe
和toEqual
的最佳实践(不仅在Jest中,而且在其他测试框架中也是如此)?
5条答案
按热度按时间carvr3hs1#
它失败的原因是
x
和y
是不同的示例,不像(x === y) === false
中那样相等。您可以使用toBe
来处理字符串、数字或布尔值等原语,其他所有内容都可以使用toEqual
。举个例子即使是空的物体也不相等
xwbd5t1u2#
假设有两个同名的球员,他们都得分20。
现在我有一个函数,它给了我第一个玩家。
如何测试此功能?
toBe
测试Identity,toEqual
测试特性。所以双胞胎孩子可以有相同的特征,但他们的真实的身份是不同的。这个函数的设计方式我们应该使用toBe
。现在我有另一个功能,可以增加玩家得分。
如何测试此功能?
你有没有注意到,在第一条路中,我们正在通过一个新的球员,比如在右手边的实体。
player1
是否有可能与新创建的实体具有相同的身份?所以toBe
在这种情况下总是失败。第二种方法是在
toEqual
中比较特征。这里player1
和新创建的实体具有相同的特性。**注意:**在javascript的上下文中,像
"Amit"
这样的原始值本身就是同一性。所以呢我已经写了这个答案的特定情况下,当你得到这个想法的身份和功能,你可以实现它在您的场景。
nlejzf6q3#
这都是关于对象引用的。
.toBe
比较原始值或检查对象示例的引用标识,而toEqual
查找深度相等。第二个Assert失败,因为它们是不同的示例,即使它们完全相等。记住,对象文字语法创建了基对象的一个新示例。
这里,赋值运算符将存储在变量
a
中的对象引用复制到b
。Assert通过是因为'a'和'b'指向同一个对象。请注意,
{ name: 'john doe' }
不是一个对象,它是一个创建对象的指令。对象存在于内存中,并通过存储在变量中的引用进行交互。50few1ms4#
你也有
toStrictEqual()
自Jest v23说明:https://jestjs.io/docs/en/expect#tostrictequalvalue
有一个ESLint plugin for Jest,它有一个强制执行
toStrictEqual()
的规则:https://github.com/jest-community/eslint-plugin-jest/blob/master/docs/rules/prefer-strict-equal.mdnpm install --save-dev eslint-plugin-jest
yizd12fk5#
有一些人说
.toBe()
和x === y
是一样的,但实际上略有不同。Jest在执行expect(x).toBe(y)
时使用Object.is(x, y)
。除非你正在验证一个值是否与一个引用相同(比如检查某个东西是否正确地被深度克隆),否则你应该总是使用
.toEqual()
。即使在deepclone示例中,我认为只执行expect(x === y).toEqual(true)
更清晰,只是为了消除对您正在尝试做的事情的任何混淆。您不应该期望其他人知道
toBe
和toEqual
之间的区别,或者甚至知道Object.is
的存在以及它与===
的区别。为了避免通信问题和测试问题,请始终使用.toEqual
,不要使用.toBe
。我已经写了一个更详细的版本作为博客文章: