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

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

You have also toStrictEqual() since Jest v23

Explanations: https://jestjs.io/docs/en/expect#tostrictequalvalue

There is an ESLint plugin for Jest with a rule to enforce toStrictEqual(): https://github.com/jest-community/eslint-plugin-jest/blob/master/docs/rules/prefer-strict-equal.md

npm install --save-dev eslint-plugin-jest

// .eslintrc.js
module.exports = {
  extends: [
    'plugin:jest/recommended'
  ],

  rules: {
    'jest/prefer-strict-equal': 'error'
  }
}

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.

Tags:

Testing

Jestjs