Jest · Unit tests that survive refactors
How do you write parameterized tests with test.each?
Short answer
test.each runs one test body over a table of inputs and reports which row failed. Use it for related cases with the same logic; avoid it when cases need different setup or assertions.
Duplicating the same test with different numbers is noisy and easy to update inconsistently. test.each keeps the cases in one table and generates a separate test per row, so a failure identifies the exact input that broke.
test.each([
[0, 0],
[1, 1],
[2, 4],
[-3, 9],
])("squares %i to %i", (input, expected) => {
expect(square(input)).toBe(expected);
});
test.each([
["", false],
["asha@example.com", true],
])("validates %s as %s", (email, valid) => {
expect(isValidEmail(email)).toBe(valid);
});When a table is the right tool
- The same assertion logic applies to every row
- The inputs are small and readable as data
- The test name benefits from showing the case values
- The cases are boundary values, invalid inputs or equivalence classes
A table is a poor fit when rows need different setup, different assertions or different mocks. For example, a success case and a permission-denied case usually deserve separate tests. describe.each exists for sharing a set of tests across fixtures, but it is easy to overuse.
%s for strings, %i for integers, %j for JSON and %o for an object. For object rows, the array-of-arrays form is easier to read than array-of-objects with tagged template syntax.Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1When is test.each worse than separate tests?
- 2How do you name each row helpfully?
- 3What is describe.each used for?
- 4How do you pass objects to test.each?
Say it in the interview
test.each generates one test per row from a table of inputs. I use it when every row shares the same assertion logic, like boundary values for a pure function, because a failure names the exact input. I avoid it when cases need different setup or different expected behaviour, since that hides the intent. The printed case values are the main readability benefit.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Jest mock interview and get scored feedback on depth, clarity and confidence.