Jasmine JavaScript测试 - toBe vs toEqual

本文翻译自:Jasmine JavaScript Testing - toBe vs toEqual

Let's say I have the following: 假设我有以下内容:

var myNumber = 5;
expect(myNumber).toBe(5);
expect(myNumber).toEqual(5);

Both of the above tests will pass. 上述两项测试都将通过。 Is there a difference between toBe() and toEqual() when it comes to evaluating numbers? 在评估数字时, toBe()toEqual()之间有区别吗? If so, when I should use one and not the other? 如果是这样,我应该使用一个而不是另一个?


#1楼

参考:https://stackoom.com/question/1W2e9/Jasmine-JavaScript测试-toBe-vs-toEqual


#2楼

toBe() versus toEqual() : toEqual() checks equivalence. toBe()toEqual()toEqual()检查等价。 toBe() , on the other hand, makes sure that they're the exact same object. 另一方面, toBe()确保它们是完全相同的对象。

I would say use toBe() when comparing values, and toEqual() when comparing objects. 我要说的使用toBe()比较值时,和toEqual()比较对象时。

When comparing primitive types, toEqual() and toBe() will yield the same result. 比较基元类型时, toEqual()toBe()将产生相同的结果。 When comparing objects, toBe() is a stricter comparison, and if it is not the exact same object in memory this will return false. 比较对象时, toBe()是一个更严格的比较,如果它不是内存中完全相同的对象,则返回false。 So unless you want to make sure it's the exact same object in memory, use toEqual() for comparing objects. 因此,除非您想确保它与内存中的完全相同,否则请使用toEqual()来比较对象。

Check this link out for more info : http://evanhahn.com/how-do-i-jasmine/ 查看此链接了解更多信息: http//evanhahn.com/how-do-i-jasmine/

Now when looking at the difference between toBe() and toEqual() when it comes to numbers, there shouldn't be any difference so long as your comparison is correct. 现在,当查看数字时toBe()toEqual()之间的区别时,只要您的比较正确,就不会有任何差别。 5 will always be equivalent to 5 . 5将始终相当于5

A nice place to play around with this to see different outcomes is here 玩弄此看到不同的结果,一个好的地方是这里

Update 更新

An easy way to look at toBe() and toEqual() is to understand what exactly they do in JavaScript. 查看toBe()toEqual()的简单方法是了解它们在JavaScript中的作用。 According to Jasmine API, found here : 根据Jasmine API,在这里找到:

toEqual() works for simple literals and variables, and should work for objects toEqual()适用于简单的文字和变量,应该适用于对象

toBe() compares with === toBe()与===进行比较

Essentially what that is saying is toEqual() and toBe() are similar Javascripts === operator except toBe() is also checking to make sure it is the exact same object, in that for the example below objectOne === objectTwo //returns false as well. 基本上所说的是toEqual()toBe()是类似的Javascripts ===运算符,除了toBe()也检查以确保它是完全相同的对象,在下面的示例中objectOne === objectTwo //returns false However, toEqual() will return true in that situation. 但是,在这种情况下, toEqual()将返回true。

Now, you can at least understand why when given: 现在,你至少可以理解给出的原因:

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

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

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

That is because, as stated in this answer to a different, but similar question, the === operator actually means that both operands reference the same object, or in case of value types, have the same value. 这是因为,正如对这个不同但类似问题的答案中所述, ===运算符实际上意味着两个操作数引用相同的对象,或者在值类型的情况下,具有相同的值。


#3楼

To quote the jasmine github project, 引用jasmine github项目,

expect(x).toEqual(y); compares objects or primitives x and y and passes if they are equivalent 比较对象或基元x和y,如果它们是等价的则传递

expect(x).toBe(y); compares objects or primitives x and y and passes if they are the same object 比较对象或基元x和y, 如果它们是同一个对象则传递


#4楼

For primitive types (eg numbers, booleans, strings, etc.), there is no difference between toBe and toEqual ; 对于原始类型(例如数字,布尔值,字符串等), toBetoEqual之间没有区别; either one will work for 5 , true , or "the cake is a lie" . 任何一个人都会工作5true ,或"the cake is a lie"

To understand the difference between toBe and toEqual , let's imagine three objects. 要理解toBetoEqual之间的区别,让我们想象三个对象。

var a = { bar: 'baz' },
    b = { foo: a },
    c = { foo: a };

Using a strict comparison ( === ), some things are "the same": 使用严格的比较( === ),有些东西是“相同的”:

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

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

> c.foo === b.foo
true

But some things, even though they are "equal", are not "the same", since they represent objects that live in different locations in memory. 但有些东西,即使它们“相等”,也不是“相同的”,因为它们代表了生活在记忆中不同位置的物体。

> b === c
false

Jasmine's toBe matcher is nothing more than a wrapper for a strict equality comparison Jasmine的toBe matcher只不过是一个严格的平等比较的包装器

expect(c.foo).toBe(b.foo)

is the same thing as 是一样的

expect(c.foo === b.foo).toBe(true)

Don't just take my word for it; 不要只听我的话; see the source code for toBe . 看到toBe的源代码

But b and c represent functionally equivalent objects; 但是bc代表功能相同的对象; they both look like 他们俩看起来都像

{ foo: { bar: 'baz' } }

Wouldn't it be great if we could say that b and c are "equal" even if they don't represent the same object? 如果我们可以说bc “相等”,即使它们不代表同一个对象,也不是很好吗?

Enter toEqual , which checks "deep equality" (ie does a recursive search through the objects to determine whether the values for their keys are equivalent). 输入toEqual ,它检查“深度相等”(即通过对象进行递归搜索以确定其键的值是否相等)。 Both of the following tests will pass: 以下两个测试都将通过:

expect(b).not.toBe(c);
expect(b).toEqual(c);

Hope that helps clarify some things. 希望有助于澄清一些事情。


#5楼

Looking at the Jasmine source code sheds more light on the issue. 查看Jasmine源代码可以更清楚地了解这个问题。

toBe is very simple and just uses the identity/strict equality operator, === : toBe非常简单,只使用identity / strict相等运算符, ===

  function(actual, expected) {
    return {
      pass: actual === expected
    };
  }

toEqual , on the other hand, is nearly 150 lines long and has special handling for built in objects like String , Number , Boolean , Date , Error , Element and RegExp . 另一方面, toEqual近150行,并且对内置对象(如StringNumberBooleanDateErrorElementRegExp特殊处理。 For other objects it recursively compares properties. 对于其他对象,它递归地比较属性。

This is very different from the behavior of the equality operator, == . 这与等于运算符==的行为非常不同。 For example: 例如:

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

#6楼

Thought someone might like explanation by (annotated) example: 以为有人可能会通过(带注释的)示例来解释:

Below, if my deepClone() function does its job right, the test (as described in the 'it()' call) will succeed: 下面,如果我的deepClone()函数正常工作,那么测试(如'it()'调用中所述)将成功:

describe('deepClone() array copy', ()=>{
    let source:any = {}
    let clone:any = source
    beforeAll(()=>{
        source.a = [1,'string literal',{x:10, obj:{y:4}}]
        clone = Utils.deepClone(source) // THE CLONING ACT TO BE TESTED - lets see it it does it right.
    })
    it('should create a clone which has unique identity, but equal values as the source object',()=>{
        expect(source !== clone).toBe(true) // If we have different object instances...
        expect(source).not.toBe(clone) // <= synonymous to the above. Will fail if: you remove the '.not', and if: the two being compared are indeed different objects.
        expect(source).toEqual(clone) // ...that hold same values, all tests will succeed.
    })
})

Of course this is not a complete test suite for my deepClone(), as I haven't tested here if the object literal in the array (and the one nested therein) also have distinct identity but same values. 当然,这不是我的deepClone()的完整测试套件,因为我没有在这里测试过数组中的对象文字(以及嵌套在其中的对象文字)是否也具有不同的标识但是具有相同的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章