3

Using Angular 8, @angular-builders/jest 8.0.2, jest 24.8, and given the following test passes

import { tick, fakeAsync } from '@angular/core/testing';

it('test 1000 milliseconds', fakeAsync(() => {
    const fn = jest.fn();
    setTimeout(() => {
        fn();
    }, 1000);

    tick(999);
    expect(fn).not.toHaveBeenCalled();
    tick(1);
    expect(fn).toHaveBeenCalled();
}));

I wanted to write several similar tests using it.each

it.each([[1000], [2000], [3000]])(
    'test %d milliseconds',
    fakeAsync(milliseconds => {
        const fn = jest.fn();
        setTimeout(() => {
            fn();
        }, milliseconds);

        tick(milliseconds - 1);
        expect(fn).not.toHaveBeenCalled();
        tick(1);
        expect(fn).toHaveBeenCalled();
    }),
);

but I got this error on each test:

Expected to be running in 'ProxyZone', but it was not found.

    at Function.Object.<anonymous>.ProxyZoneSpec.assertPresent (node_modules/zone.js/dist/proxy.js:42:19)
    at node_modules/zone.js/dist/fake-async-test.js:588:47

What am I missing ?

Sergio Mazzoleni
  • 1,458
  • 15
  • 24
  • Did you found a fix? – distante Jun 28 '19 at 12:12
  • @distante: Not as neat as I would like, but as a workaround, I wrapped a standard `it` with a `describe.each` so that I can use `fakeAsync` without issue. That does the job but adds some noise in spec file and in the console output – Sergio Mazzoleni Jun 28 '19 at 21:35
  • 1
    Thank you. You should consider write an answer to your question. Maybe it isn't pretty as you said but it could help other people to find a better way. – distante Jun 29 '19 at 05:18

2 Answers2

5

So far, the best workaround I thought of was to move the each part to a describe wrapper so that fakeAsync is used in a "classic" it.

describe.each([[1000], [2000], [3000]])(
    'test %d milliseconds',
    milliseconds => {
        it('', fakeAsync(() => {
            const fn = jest.fn();
            setTimeout(() => {
                fn();
            }, milliseconds);

            tick(milliseconds - 1);
            expect(fn).not.toHaveBeenCalled();
            tick(1);
            expect(fn).toHaveBeenCalled();
        }));
    },
);

It adds some noise to the test code and to the console output, but at least, the tests now pass.

justinsg
  • 738
  • 6
  • 11
Sergio Mazzoleni
  • 1,458
  • 15
  • 24
0

This appears to be an issue with jest-preset-angular and the zone-patch file. It doesn't patch it.each or test.each to run in a fakeAsync zone. I have submitted a bug https://github.com/thymikee/jest-preset-angular/issues/339

Andrew Alderson
  • 968
  • 5
  • 16