Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest compare object with arbitrary property value

I'm testing rest API with Jest. I know we use toEqual to check whether two objects are equal or not by recursively compare all the properties.

For primitive values toEqual uses Object.is for the comparison.

Problem

The problem I'm having is while testing /register endpoint. After once a user successfully registered, the endpoint returns the user details. Use details contain information like phone, name, email, and what is more important in this case a user_id.

Now, what I'm trying is like this:

const data = {
  sponsor_id: 'ROOT_SPONSOR_ID',
  phone: '9999999999',
  name: 'Joe',
  password: 'shhhhh'
};

// Some API call goes here which returns `body`

expect(body).toEqual({
  user_id, // <-- How to test value of this?
  sponsor_id: data.sponsor_id,
  phone: data.phone,
  name: data.name
});

I don't know beforehand what would be the returned value of user_id field. All I know that it would be a Number. Now it can be any numeric value so how to test an object property with any value or any numeric value in this case?

One thing that I also wanted to check that I'm sending any extra data (properties) than what I'm expecting. Which by the way using toEqual is taking care of already.

If my approach of the way I'm testing this is flawed then please provide me with a better one with some explanation.

like image 382
Aziz Avatar asked Feb 23 '19 05:02

Aziz


People also ask

What is a matcher 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's the difference between the toBe and toEqual matchers in jest?

. toBe compares primitive values or checks referential identity of object instances while toEqual looks for deep equailty.


1 Answers

Use expect.any(Number) to ensure that user_id is a Number:

test('matches', () => {

  const data = {
    sponsor_id: 'ROOT_SPONSOR_ID',
    phone: '9999999999',
    name: 'Joe',
    password: 'shhhhh'
  };

  const user_id = Math.floor(Math.random() * 1000);
  const body = Object.assign(data, { user_id });

  expect(body).toEqual({
    user_id: expect.any(Number),  // user_id must be a Number
    sponsor_id: data.sponsor_id,
    phone: data.phone,
    name: data.name,
    password: data.password
  });  // SUCCESS

});

Note that if you want an even more specific matcher you can create your own using expect.extends.

like image 146
Brian Adams Avatar answered Oct 23 '22 02:10

Brian Adams