1

I'm trying to do parameterized testing with Jest 24

https://archive.jestjs.io/docs/en/24.x/api#2--testeachtablename-fn-timeout-

My test looks like:

  it.each`
    startDate                 | endDate                   | expected
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 21)}  | 1
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 22)}  | 1
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 23)}  | 1
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 24)}  | 2
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 29)}  | 7
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 30)}  | 7
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 31)}  | 8
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 2, 1)}   | 9
  `('weekend days are not counted', ({startDate, endDate, expected}) => {
    ...
  });

But when I run it:

    Not enough arguments supplied for given headings:
    startDate | endDate | expected

    Received:
    Array [
      2022-02-20T00:00:00.000Z,
      2022-02-21T00:00:00.000Z,
      2022-02-20T00:00:00.000Z,
      2022-02-22T00:00:00.000Z,
      2022-02-20T00:00:00.000Z,
      2022-02-23T00:00:00.000Z,
      2022-02-20T00:00:00.000Z,
      2022-02-24T00:00:00.000Z,
      2022-02-20T00:00:00.000Z,
      2022-03-01T00:00:00.000Z,
      2022-02-20T00:00:00.000Z,
      2022-03-02T00:00:00.000Z,
      2022-02-20T00:00:00.000Z,
      2022-03-03T00:00:00.000Z,
      2022-02-20T00:00:00.000Z,
      2022-03-01T00:00:00.000Z,
    ]

    Missing 1 argument

Can someone explain what is wrong?

Anentropic
  • 32,188
  • 12
  • 99
  • 147

1 Answers1

0

Note the docs say the values in the table must be:

One or more subsequent rows of data supplied as template literal expressions using ${value} syntax.

In your case that means:

  it.each`
    startDate                 | endDate                   | expected
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 21)}  | 1
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 22)}  | 1
  `('weekend days are not counted', ({startDate, endDate, expected}) => {
    ...
  });

should be:

  it.each`
    startDate                 | endDate                   | expected
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 21)}  | ${1}
    ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 22)}  | ${1}
  `('weekend days are not counted', ({startDate, endDate, expected}) => {
    ...
  });

with the expected value interpolated as well. This is due to the way tagged templates work; without the braces the value 1 ends up in the strings array, the first argument to the function, rather than the subsequent expression arguments.


You can see in a bit more detail what's happening by defining a simple function to show what it.each is actually acting on:

> function reveal(strings, ...args) {
... return JSON.stringify({ strings, args }, null, 2);
... }
undefined
> console.log(reveal`
...     startDate                 | endDate                   | expected
...     ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 21)}  | 1
...     ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 22)}  | 1
...   `)
{
  "strings": [
    "\n    startDate                 | endDate                   | expected\n    ",
    "  | ",
    "  | 1\n    ",
    "  | ",
    "  | 1\n  "
  ],
  "args": [
    "2022-02-20T00:00:00.000Z",
    "2022-02-21T00:00:00.000Z",
    "2022-02-20T00:00:00.000Z",
    "2022-02-22T00:00:00.000Z"
  ]
}
undefined
> console.log(reveal`
...     startDate                 | endDate                   | expected
...     ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 21)}  | ${1}
...     ${new Date(2022, 1, 20)}  | ${new Date(2022, 1, 22)}  | ${1}
...   `)
{
  "strings": [
    "\n    startDate                 | endDate                   | expected\n    ",
    "  | ",
    "  | ",
    "\n    ",
    "  | ",
    "  | ",
    "\n  "
  ],
  "args": [
    "2022-02-20T00:00:00.000Z",
    "2022-02-21T00:00:00.000Z",
    1,
    "2022-02-20T00:00:00.000Z",
    "2022-02-22T00:00:00.000Z",
    1
  ]
}
undefined

Generally in cases like these I'd be inclined to use vanilla JS language features anyway:

[
  [new Date(2022, 1, 20), new Date(2022, 1, 21), 1],
  [new Date(2022, 1, 20), new Date(2022, 1, 22), 1]
].forEach(([startDate, endDate, expected]) => {
  it('weekend days are not counted', () => {
    ...
  });
});
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • ah thanks! I was worried it was something to do with the dates and didn't notice the innocuous number hadn't been interpolated ‍♂️ – Anentropic Jan 21 '22 at 17:22