Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare objects containing anonymous functions on jest testcase

I am using jest on a ReactNative project. I would like to compare in a test case two objects of the same class. Here is an example class definition:

class Person {
    constructor(id, name, lastName) {
        this.id = id;
        this.name = name;
        this.lastName = lastName;
    }       

    fullName = () => {
        return `${this.name} ${this.lastName}`;
    }
}

I created a test case which compared two objects of the Person class which should be identical:

test('checks the Person.constructor method', () => {
    expect(new Person(1, 'John', 'Smith')).toEqual(new Person(1, 'John', 'Smith'));
});

However I get the following result:

 FAIL  __tests__/Comparison-test.js (7.328s)
  ● checks the Person.constructor method

    expect(received).toEqual(expected)

    Expected: {"fullName": [Function anonymous], "id": 1, "lastName": "Smith", "name": "John"}
    Received: {"fullName": [Function anonymous], "id": 1, "lastName": "Smith", "name": "John"}

      48 | 
      49 | test('checks the Person.constructor method', () => {
    > 50 |     expect(new Person(1, 'John', 'Smith')).toEqual(new Person(1, 'John', 'Smith'));
         |                                            ^
      51 | });

      at Object.toEqual (__tests__/Comparison-test.js:50:44)

Comparing the expected and received values, visually I can see they're identical, however I know they're not considered identical because of the anonymous function fullName.

How can I compare both objects? I would like to be able to disconsider the anonymous functions, even though the function is identical in both objects.

I tried using the expect function, by setting lastName to expect.anything(). The test below actually passed:

test('checks the Person.constructor method', () => {
    expect(new Person(1, 'John', 'Smith')).toEqual({
        id: 1,
        name: 'John',
        lastName: 'Smith',
        fullName: expect.anything()});
});

However this isn't really desirable, because I would have to list all functions of the class being tested, and if I add more functions to a class all of its tests will break.

So, is there a way of comparing two objects of the same class in jest ignoring all functions of those objects?

Thanks!

like image 905
Felipe Ferri Avatar asked Mar 21 '19 18:03

Felipe Ferri


1 Answers

Sounds like you want toMatchObject which matches "a subset of the properties of an object":

test('checks the Person.constructor method', () => {
  expect(new Person(1, 'John', 'Smith')).toMatchObject({
    id: 1,
    name: 'John',
    lastName: 'Smith'
  });  // Success!
});

Update

OP asked in the comments if there is any way to still use the instances.

It also works to serialize the objects using JSON.stringify and compare the results:

test('checks the Person.constructor method', () => {
  expect(JSON.stringify(new Person(1, 'John', 'Smith')))
    .toBe(JSON.stringify(new Person(1, 'John', 'Smith')));  // Success!
});
like image 63
Brian Adams Avatar answered Oct 25 '22 20:10

Brian Adams