Custom classes in Jest diffs

Viewed 77

Assuming I have a class like this:

class Cat {
  constructor(name) {
    this.name = name;
  }
}

and a failing test like this:

expect(new Cat('Bob')).toEqual(new Cat('Alice'));

Instead of:

    - Expected  - 1
    + Received  + 1

      Cat {
    -   "name": "Alice",
    +   "name": "Bob",
      }

I would like to see e.g. (doesn't have to be exactly like this, just in some way customizable):

    Expected: "Cat named Alice"
    Received: "Cat named Bob"

I tried defining a toString() method and get [Symbol.toStringTag](). The former did nothing, the latter helped with console.log but not with Jest's diff. Is there any way to achieve this?

2 Answers
expect.extend({
  toBeValid(received, validator) {
    if (validator(received)) {
      return {
        message: () => `Received: "Cat named ${received}"`,
        pass: true
      };
    } else {
      return {
        message: () => `Received: "Cat named ${received}"`,
        pass: false
      };
    }
  }
});

You can extend the expect function call and return the expected message. https://jestjs.io/docs/expect#expectextendmatchers

expect.extend({
  toEqual(expected, received) {
    if (expected.name !== received.name) {
      return {
        message: () => `
          Expected: "Cat named ${expected.name}"
          Received: "Cat named ${received.name}"
        `,
        pass: false
      };
    }
    return true;
  }
});

describe("a", () => {
  it("b", () => {
    expect(new Cat("Bob")).toEqual(new Cat("Alice"));
  });
});

Here you can find the working demo. https://codesandbox.io/s/jest-test-forked-8ef0f?file=/index.test.js:28-432

Hope this is helpful.

Related