How to Loop in Jest Unit Tests

Last Updated:
How to loop jest unit tests

Sometimes when writing Jest unit tests you are going to want to be able to loop over items to quickly test different cases. Whether this be looping over an array of items, or counting between numbers in your Jest Test. This will massively simplify your Jest test suite.

There are a number of ways to do this. This post aims to outline the ways that I have looped through Jest tests in the past.

Looping over tests with Jest.Each

For very basic repetitive Jest tests I would use jest.each. It allows you to keep duplicating the same test with different data. You can write the test once and let the data do the work.

Using Basic Arrays and printf

An example of this is:

test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('.add(%i, %i)', (a, b, expected) => {
  expect(a + b).toBe(expected);
});

The above code is taking in a set of data within an array, The name of the test using printf to inject parameters into the text, and the arguments to be passed into the test itself.

For more information about jest.each take a look at the Jest documentation.

Using Array of Objects

Rather than using printf, you can pass in an array of objects and reference them using string literals. Like so:

test.each([
  {a: 1, b: 1, expected: 2},
  {a: 1, b: 2, expected: 3},
  {a: 2, b: 1, expected: 3},
])('.add($a, $b)', ({a, b, expected}) => {
  expect(a + b).toBe(expected);
});

I personally prefer this. It is more explicit in what each item is, and allows you to build a more complex test data set. It is a nice way of being able to Jest test each array of objects – and cleanly see what is expected for each item.

Using Jest.Each with a Table

The jest.each API also lets you pass data into it in a more ‘visual’ way. Using one large string literal you can shape the data in a table.

This looks like:

test.each`
  a    | b    | expected
  ${1} | ${1} | ${2}
  ${1} | ${2} | ${3}
  ${2} | ${1} | ${3}
`('returns $expected when $a is added $b', ({a, b, expected}) => {
  expect(a + b).toBe(expected);
});

The first row sets up the table headings, and the rest of the rows using template literals to add the values. Then the test title itself using template literals to inject the data into the string.

Not my top choice, but some people like this way of handling the tests.

Using a For Loop in Jest Tests

The for loop is my go to when wanting to dynamically loop through Jest tests.  In this way of writing loops in jest there is no need for the printf variable injection. Call me old fashioned (or wrong), but I also like the flexibility of being able to fully control the tests, and how they are created. This way of testing also makes the Jest tests portable between test frameworks, as they are not tied in with specific semantics. Another bonus is IDE support – a simple for loop will be picked up, a jest each is less likely to be.

The for loop approach allows me to loop describe jest test blocks, as well as the unit tests inside. However with this freedom comes the need to restrict yourself. Otherwise the tests could become to over-engineered and end up being too confusing.

Simple tests are better.

const testData = [
    { a: 1, b: 1, expected: 2 },
    { a: 1, b: 2, expected: 3 },
    { a: 2, b: 1, expected: 3 }
];

for (let i = 0; i < testData.length; i += 1) { it(`.add(${testData[i].a}, ${testData[i].b})`, () => {
        expect(testData[i].a + testData[i].b).toBe(testData[i].expected);
    });
}

The above shows how the for loop would be used to create dynamically generated Jest tests.

What About looping Jest tests with forEach?

I have asked if the same flow can be achieved putting Jest test cases in a forEach loop. It is possible for smaller synchronous tests – however you cannot use forEach loops with async/await so I wouldn’t recommend using it. You can read more about why here.

Jest test.each vs. forEach vs. for

JavaScript’s vanilla for is the clear winner for me. It is easy to write, not tied into specific frameworks, and is easy to understand. I wouldn’t say not to use jest.each as it has its uses for simpler tests. I would never use forEach.

 

For a break down of Jest and React Testing Library take a look at this short overview.

 

For more Jest hints and tips take a look at the Jest Testing Category!

Hopefully this helped you, and if you have any questions you can reach me at: @robertmars

 

 

Related Posts

Get helpful Jest Pieces right to your inbox

Keep up to date with all helpful bits of Jest snippets and articles.