Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass in the done() parameter on an async jest test.each case

Tags:

jestjs

ts-jest

I'm trying write a jest test case that tests an async method, I want to pass in the done() parameter so jest waits for it to be fired before it ends the test, however, I'm not sure where to put it.

Any ideas?

const testcases = [
        [
            'Crew',
            [1,2,3],
            Enum.Level1
        ],
        [
            'Staff',
            [4,5,6],
            Enum.Level2
        ]
    ];
test.each(testcases )(
        'Should be able to load differing cases %p',
        (
            typeName: string,
            initalVals: string[],
            type: LevelType
        ) => {
            // some call that updates mobx store state

            when(
                () => mobxstoreProperty.length == initalVals.length,
                () => {
                    // my assertions

                    done();
                }
            );
        }
    );

For a single jest test I can do this:

test('my single test', done => {
  // some call that updates mobx store state

     when(
       () => mobxstoreProperty.length == initalVals.length,
       () => {
         // my assertions
         done();
       }
    );
});

Just unsure how to do it for when I use the test.each method.

like image 663
uneatenbreakfast Avatar asked Jan 27 '20 23:01

uneatenbreakfast


People also ask

What does done () do in Jest?

Instead of putting the test in a function with an empty argument, use a single argument called done . Jest will wait until the done callback is called before finishing the test.

Which sequence allows for testing a property without waiting for an asynchronous update?

In cases where the property is set before the appendChild() call, the component is rendered synchronously. When the property is set before the appendChild() call, you don't need to wait for asynchronous updates or return a promise.

How do you wait in Jest test?

Just return a promise from your test, and Jest will wait for that promise to resolve. If the promise is rejected, the test will automatically fail. Be sure to return the promise - if you omit this return statement, your test will complete before fetchData completes.


2 Answers

I use named parameters and I can add the done() method as the last function parameter. For example like so:

const testcases: {
    typeName: string;
    initalVals: string[],
    type: LevelType
}[] = [
    {
        typeName: 'Crew',
        initalVals: [1,2,3],
        type: Enum.Level1
    },
    {
        typeName: 'Staff',
        initalVals: [4,5,6],
        type: Enum.Level2
    },
];
test.each(testcases)(
    'Should be able to load differing cases %p',
    // Must use `any` for `done`, as TypeScript infers the wrong type:
    ({typeName, initalVals, type}, done: any) => {
        // some call that updates mobx store state
        when(
            () => mobxstoreProperty.length == initalVals.length,
            () => {
                // my assertions

                done();
            }
        );
    }
);

I haven't tested if you can just add the done() method as last parameters with array arguments, but maybe that works, too.

like image 101
schemar Avatar answered Oct 08 '22 12:10

schemar


to pass and evaluate done, the done callback should be very last argument in the function for test case arguments.

also, here's how to deal with typings, when you use the test.each method in typescript:

// found at https://github.com/DefinitelyTyped/DefinitelyTyped/issues/34617

it.each<number | jest.DoneCallback>([1, 2, 3])(
    'dummy: %d',
    (num: number, done: jest.DoneCallback) => {
        done();
    },
);
like image 24
voznik Avatar answered Oct 08 '22 10:10

voznik