Jasmine JavaScript测试 - toBe vs toEqual

Llo*_*nks 319 javascript jasmine

假设我有以下内容:

var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);
Run Code Online (Sandbox Code Playgroud)

上述两项测试都将通过.有没有之间的差异toBe(),并toEqual()当它涉及到评估的数字?如果是这样,我应该使用一个而不是另一个?

小智 453

对于原始类型(例如数字,布尔值,字符串等),toBe和之间没有区别toEqual; 任何一个可以为工作5,true"the cake is a lie".

要理解之间的区别toBetoEqual,假设三个对象.

var a = { bar: 'baz' },
    b = { foo: a },
    c = { foo: a };
Run Code Online (Sandbox Code Playgroud)

使用严格的比较(===),有些东西是"相同的":

> b.foo.bar === c.foo.bar
true

> b.foo.bar === a.bar
true

> c.foo === b.foo
true
Run Code Online (Sandbox Code Playgroud)

但有些东西,即使它们"相等",也不是"相同的",因为它们代表了生活在记忆中不同位置的物体.

> b === c
false
Run Code Online (Sandbox Code Playgroud)

Jasmine的toBe匹配器只不过是一个严格的平等比较的包装器

expect(c.foo).toBe(b.foo)
Run Code Online (Sandbox Code Playgroud)

是一样的

expect(c.foo === b.foo).toBe(true)
Run Code Online (Sandbox Code Playgroud)

不要只听我的话; 看到toBe的源代码.

但是,bc代表功能等价物; 他们俩看起来都像

{ foo: { bar: 'baz' } }
Run Code Online (Sandbox Code Playgroud)

如果我们可以说b并且c"平等"即使它们不代表同一个对象,也不是很好吗?

Enter toEqual,检查"深度相等"(即通过对象进行递归搜索以确定其键的值是否相等).以下两个测试都将通过:

expect(b).not.toBe(c);
expect(b).toEqual(c);
Run Code Online (Sandbox Code Playgroud)

希望有助于澄清一些事情.

  • "对于原始类型(例如数字,布尔值,字符串等),toBe和toEqual之间没有区别" - 因为事实证明这并非完全正确.`expect(0).toBe(-0)`将通过但是`expect(0).toEqual(-0)`将失败. (16认同)
  • tl; dr - `toBe`使用严格相等 - 通过引用进行比较,`toEqual`使用属性等价.建议使用`toEqual`作为基元 (8认同)
  • 那么我们应该为基元使用哪一个,为什么?Drenai,你为什么推荐toEqual? (3认同)

Adj*_*jit 77

toBe()toEqual():toEqual()检查等价.toBe()另一方面,确保它们是完全相同的对象.

我会说toBe()比较值和toEqual()比较对象时使用.

当比较基本类型,toEqual()toBe()会产生相同的结果.比较对象时,toBe()是一个更严格的比较,如果它不是内存中完全相同的对象,则返回false.因此,除非您想确保它与内存中的完全相同,否则请toEqual()用于比较对象.

查看此链接了解更多信息:http://evanhahn.com/how-do-i-jasmine/

现在,当看着之间的差异toBe(),并toEqual()当它涉及到数字,不应该有任何区别,只要你的比较是正确的.5永远等同于5.

玩弄此看到不同的结果,一个好的地方是这里

更新

一个简单的方法来看待toBe()toEqual()是了解他们在JavaScript中做什么.根据Jasmine API,在这里找到:

toEqual()适用于简单的文字和变量,应该适用于对象

toBe()与 ===

本质上是说toEqual()toBe()Javascripts ===运算符是相似的,除了toBe()还要检查以确保它是完全相同的对象,在下面的示例中objectOne === objectTwo //returns false也是如此.但是,toEqual()在那种情况下会返回true.

现在,你至少可以理解给出的原因:

var objectOne = {
    propertyOne: str,
    propertyTwo: num    
}

var objectTwo = {
    propertyOne: str,
    propertyTwo: num    
}
Run Code Online (Sandbox Code Playgroud)

expect(objectOne).toBe(objectTwo); //returns false

这是因为,在说明这个答案不同,但类似的问题,===运营商实际上意味着两个操作数引用同一个对象,或在值类型的情况下,具有相同的值.

  • 这不仅没有回答这个问题,而且是错误的***.`toEqual`应该用于对象之间的深度比较,而不是`toBe`.http://jsfiddle.net/bBL9P/67/ (8认同)
  • 这是完全错误的.`toEqual`是**根本不是**和`==`相同. (6认同)
  • 阅读上面的评论.`expect(1).toEqual('1')`失败,而`1 =='1'`为真.`toEqual`与`==`无关.它就像`===`,除了它将以类似于按值比较的方式比较对象. (6认同)
  • 这避免了回答这个问题.你通过说*`toEqual()`检查等价*来解释`toEqual()`的作用,但明显的下一个问题是*好的,那么"等价"是什么意思?*用于确定"等价"的算法的描述"或者至少`toEqual()`和`toBe()`的行为不同的情况的例子会使这更有用. (4认同)
  • 看起来人们似乎并不打算测试他们所说的是否正确.toBe和toEqual似乎都是严格的比较.测试它...所以在我的测试中我还没有找到差异.例如:var f = 1; var g ="1"expect(f == g).toEqual(true); // true expect(f).toEqual(g); // false expect(f).toBe(g); // false (3认同)

Tha*_*aka 30

引用jasmine github项目,

expect(x).toEqual(y); 比较对象或基元x和y,如果它们是等价的则传递

expect(x).toBe(y);比较对象或基元x和y,如果它们是同一个对象则传递


Tam*_*lyn 14

查看Jasmine源代码可以更清楚地了解这个问题.

toBe非常简单,只使用identity/strict相等运算符===:

  function(actual, expected) {
    return {
      pass: actual === expected
    };
  }
Run Code Online (Sandbox Code Playgroud)

toEqual,在另一方面,是近150线长,具有内置状物体特殊处理String,Number,Boolean,Date,Error,ElementRegExp.对于其他对象,它递归地比较属性.

这与等于运算符的行为非常不同==.例如:

var simpleObject = {foo: 'bar'};
expect(simpleObject).toEqual({foo: 'bar'}); //true
simpleObject == {foo: 'bar'}; //false

var castableObject = {toString: function(){return 'bar'}};
expect(castableObject).toEqual('bar'); //false
castableObject == 'bar'; //true
Run Code Online (Sandbox Code Playgroud)