Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What are the advantages to writing nested Jest expects?

I often use and come across a pattern like this when reading and writing tests:

test('should contain specific value in object', () => {
    const object = {
        specific: 'specific value',
        other: 'other',
    };
     
    expect(object).toEqual(expect.objectContaining({
        specific: 'specific value'
    }));
d});

why would you go for something like that over the following example:

test('should contain specific value in object', () => {
    const object = {
        specific: 'specific value',
        other: 'other',
    };
     
    expect(object.specific).toEqual('specific value');
d});

The second example feels more readable and still achieves the same goal, so what’s the advantage to the first one?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Compare these three tests:

describe("object comparison", () => {
    const wrongObject = { foo: "bar" };

    it("compares property directly", () => {
        expect(wrongObject.specific).toEqual("specific value");
    });

    it("uses asymmetric matcher", () => {
        expect(wrongObject).toEqual(expect.objectContaining({
            specific: "specific value",
        }));
    });

    it("uses property matcher", () => {
        expect(wrongObject).toHaveProperty("specific", "specific value");
    });
});

If they passed, there wouldn’t be much to choose between them, they express the same thing in different ways. But when they fail, compare:

  ● object comparison › compares property directly

    expect(received).toEqual(expected) // deep equality

    Expected: "specific value"
    Received: undefined

      3 |
      4 |       it("compares property directly", () => {
    > 5 |               expect(wrongObject.specific).toEqual("specific value");
        |                                            ^
      6 |       });
      7 |
      8 |       it("uses asymmetric matcher", () => {

      at Object.toEqual (path/to/demo.test.js:5:32)

  ● object comparison › uses asymmetric matcher

    expect(received).toEqual(expected) // deep equality

    - Expected  - 2
    + Received  + 2

    - ObjectContaining {
    -   "specific": "specific value",
    + Object {
    +   "foo": "bar",
      }

       7 |
       8 |      it("uses asymmetric matcher", () => {
    >  9 |              expect(wrongObject).toEqual(expect.objectContaining({
         |                                  ^
      10 |                      specific: "specific value",
      11 |              }));
      12 |      });

      at Object.toEqual (path/to/demo.test.js:9:23)

  ● object comparison › uses property matcher

    expect(received).toHaveProperty(path, value)

    Expected path: "specific"
    Received path: []

    Expected value: "specific value"
    Received value: {"foo": "bar"}

      13 |
      14 |      it("uses property matcher", () => {
    > 15 |              expect(wrongObject).toHaveProperty("specific", "specific value");
         |                                  ^
      16 |      });
      17 | });
      18 |

      at Object.toHaveProperty (path/to/demo.test.js:15:23)

The more information the test gives you about why exactly it failed ("diagnostics", to use the language from Growing Object-Oriented Software Guided by Tests by Steve Freeman and Nat Pryce), the easier it will be to figure out the problem if it does. This is one of the advantages of test-driven development; you always see the output of the failing test.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading