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()的完整測試套件,因爲我沒有在這裏測試過數組中的對象文字(以及嵌套在其中的對象文字)是否也具有不同的標識但是具有相同的值。

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