loading...

Simplify repetitive Jest test cases with test.each

bgord profile image Bartosz Gordon ・2 min read

Problem

From time to time, I run into a situation, where most of my test cases follow a similar sequence of steps. This scenario most often happens while unit testing helpers/utility functions. Given certain arguments, check if the actual result is equal to the expected result. Over and over again. As the number of cases grows, the test suite can get bloated.

Contrived example ahead:

const add = (a, b) => a + b;

describe("'add' utility", () => {
  it("given 2 and 2 as arguments, returns 4", () => {
    const result = add(2, 2);
    expect(result).toEqual(4);
  });
  it("given -2 and -2 as arguments, returns -4", () => {
    const result = add(-2, -2);
    expect(result).toEqual(-4);
  });
  it("given 2 and -2 as arguments, returns 0", () => {
    const result = add(2, -2);
    expect(result).toEqual(0);
  });
});

Solution

I thought about an abstraction to avoid this kind of boilerplate, and after a few google searches, I found the test.each Jest utility.

This helper encourages you to create the array of cases, where you store arguments and expected results, and then iterate through the entire array to run the tested function and assert the results.

Example with test.each:

const add = (a, b) => a + b;

const cases = [[2, 2, 4], [-2, -2, -4], [2, -2, 0]];

describe("'add' utility", () => {
  test.each(cases)(
    "given %p and %p as arguments, returns %p",
    (firstArg, secondArg, expectedResult) => {
      const result = add(firstArg, secondArg);
      expect(result).toEqual(expectedResult);
    }
  );
});

Notes

Benefits:

  • easier to add new tests cases
  • less boilerplate

Possible drawback:

  • more abstractions, some people may find it unnecessary

I find it worthwhile to write a comment about the items of the cases array to increase readability and reduce mental effort.

  // first argument, second argument, expected result
  const cases = [[2, 2, 4], [-2, -2, -4], [2, -2, 0]];

Discussion

markdown guide
 

This was just a nice article.Thanks so much Gordon

 

Thank you, so much easier to understand then in the docs!

 

Any idea of how to use just the second argument in the text?
"given %p and %p as arguments, returns %p",

 

You'll have to use both of them, but the convention is if you're not using a parameter you should name it a single underscore _