Jest: expect or expect...not based on Boolean

Viewed 427

Using test.each in Jest, I'd like to pass in a Boolean that toggles whether I expect something or not.

This is the type of repetitive code I'm trying to avoid:

if (expectFoo) {
  expect(anObject).toContainEqual(
    expect.objectContaining({
      name: "foo"
    })
  );
} else {
  expect(anObject).not.toContainEqual(
    expect.objectContaining({
      name: "foo"
    })
  );
}

Here is some pseudocode that illustrates my preferred (cleaner, shorter) approach:

expect(anObject).yesOrNo(expectFoo).toContainEqual(
  expect.objectContaining({
    name: "foo"
  })
);

Is there anything like this in Jest?

1 Answers

Built-in matchers aren't public API but can be imported from the same internal module that is used by Jest:

import matchers from 'expect/build/matchers';

Custom matchers can wrap and compose built-in matchers:

expect.extend({
  toContainFoo(received, expectFoo = true) {
    const isNot = !expectFoo ? !this.isNot : this.isNot
    this.isNot = isNot; // affects error message
    const expected = matchers.objectContaining({
      name: "foo"
    });
    const result = matchers.toContainEqual.call(this, received, expected);
    result.pass = !isNot; // affects assertion logic
    return result;
  }
})
Related