Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between 'toBe' and 'toEqual' in Jest?

Tags:

testing

jestjs

Jest documentation reads:

toBe just checks that a value is what you expect. It uses === to check strict equality.

And for toEqual:

Use .toEqual when you want to check that two objects have the same value. This matcher recursively checks the equality of all fields, rather than checking for object identity—this is also known as "deep equal". For example, toEqual and toBe behave differently in this test suite, so all the tests pass.

const x = { a: { b: 3 } }; const y = { a: { b: 3 } };  expect(x).toEqual(y); expect(x).toBe(y); 

In this case, toEqual passes but toBe fails. I understand that toEqual passes because it does a deep equal check. Why is toBe failing in this case?

Also, are there best practices for using toBe and toEqual (not just in Jest but in other testing frameworks, too)?

like image 259
sshh Avatar asked Jul 19 '17 15:07

sshh


People also ask

What is the difference between toBe and toEqual?

toEqual and the . toBe are equivalent, because the first thing they both check is if the values are strictly equal. So performance wise there is no difference. . toEqual just handles more cases if the strict equality fails on non-primatives.

What are matchers in Jest?

Jest uses "matchers" to let you test values in different ways. This document will introduce some commonly used matchers. For the full list, see the expect API doc.

What is the difference between describe and it in Jest?

The difference between describe and it in Jest is that describe lets us divide our test suite into sections. it is called to create individual tests which is used in the describe callback.

What is expect in Jest?

When you're writing tests, you often need to check that values meet certain conditions. expect gives you access to a number of "matchers" that let you validate different things. For additional Jest matchers maintained by the Jest Community check out jest-extended .


2 Answers

It fails cause x and y are different instances and not equal as in (x === y) === false. You can use toBe for primitives like strings, numbers or booleans for everything else use toEqual. For example

x = 4  y = 4 x === y // true  x = 'someString' y = 'someString' x === y // true 

Even empty objects are not equal

x = {} y = {} x === y //false 
like image 175
Andreas Köberle Avatar answered Sep 21 '22 13:09

Andreas Köberle


Suppose there are two players with same name and both of them scored 20.

let player1 = {     name: "Amit",     score: 20, }  let player2 = {     name: "Amit",     score: 20, } 

Now I have a function which gives me 1st player.

function getFirstPlayer(player1,player2){     return player1; } 

How will I test this function?

# 1st way expect(getFirstPlayer(player1,player2)).toBe(player1); // Passes expect(getFirstPlayer(player1,player2)).not.toBe(player2); // Passes  # 2nd way expect(getFirstPlayer(player1,player2)).toEqual(player1); // Pases expect(getFirstPlayer(player1,player2)).not.toEqual(player2); // Fails 

toBe tests Identity and toEqual tests features. So twin kids can have same features but their real identity is different from each other. The way this function is designed we should use toBe.

Now I have a another function which increases the player score.

function addScore(player,scoreToAdd){     player.score += scoreToAdd; } 

How will I test this function?

# 1st way addScore(player1,20); expect(player1).toBe({name:"Amit", score:40});  // Fails  # 2nd way addScore(player1,20); expect(player1).toEqual({name:"Amit", score:40});  // Passes 

Did you notice that in 1st way we are passing a new player like entity in right hand side. Is there any chance that player1 has the same identity of newly created entity? Nope. So toBe will always fail in this case.

2nd way passes as in toEqual we are comparing features. Here player1 and newly created entity has same features.

Note: In context of javascript, primitive values like "Amit" is identity in itself. So

expect("Amit").toBe("Amit") // Passes 

I have written this answer for particular case, when you get this idea of identity and features, you can implement it in your scenario.

like image 22
amit77309 Avatar answered Sep 23 '22 13:09

amit77309