How to match object in array strictly with Jest?

Viewed 26

I need to check that an Array contains an Object that matches a given structure.

I already tried this:

const myArray = [{ name: 'Mete', age: 19, phone: '123456' }];

expect(myArray).toEqual(          
  expect.arrayContaining([      
    expect.objectContaining({   
      name: 'Mete',
      age: 19
    })
  ])
)

// Throws no error

It should not match because the object in the array has an additional property "phone".

I need something like toStrictEqual() combined with arrayContaining().

2 Answers

With every array function, you can get the result:

const strictlyEquals = (arr, props) => arr.every(o=>Object.keys(o).every(i=>props.includes(i)));

console.log(strictlyEquals([{name:'Test', age: 20}], ['name', 'age']));
console.log(strictlyEquals([{name:'Test', age: 20, phone:'Test'}], ['name', 'age']));

If you have to match complete object then:

const strictlyEquals = (arr, props) => arr.every(o=> Object.keys(o).length===Object.keys(props).length && Object.keys(o).every(i=>o[i]===props[i]));

console.log(strictlyEquals([{name:'Test', age: 20},{name:'Test', age: 20}], {name:'Test', age: 20}));

You can use Array.prototype.some() with .toEqual(value) to test each object in the array, which will stop iteration and return true on the first assertion that passes the expectation. Otherwise, false will be returned and the final expect statement will fail.

The technique here is to catch the exceptions thrown from the assertions and convert them to false results:

const expected = {name: 'Mete', age: 19};

const myArray = [{ name: 'Mete', age: 19, phone: '123456' }];

const found = myArray.some(obj => {
  try {
    expect(obj).toEqual(expected);
    return true;
  }
  catch {
    return false;
  }
});

expect(found).toBeTruthy();

Related