angular icon indicating copy to clipboard operation
angular copied to clipboard

NoopNgZone for unit tests

Open sod opened this issue 4 years ago • 0 comments

Which @angular/* package(s) are relevant/releated to the feature request?

core, platform-browser-dynamic

Description

The introduction of NoopNgZone a few years ago was awesome ❤️ . But it was never ported to unit tests.

There is no good reason why I want this other than my distaste in the implementation of zone.js. Rxjs + async pipe + Input push change detection is perfectly fine. There is no need for 60kb of monkeypatching half the environment IMO. Maybe nicer stack traces is a plus. Or being able to use any testrunner you want without the need of extra patches.

So feel free to close if this feature wont happen.

Proposed solution

Don't hardcode in the testing modules the assumption that Zone exists and allow the use of NoopNgZone

Alternatives considered

Our current solution is a file angular-testing-noop-zone.ts with contents:

const noop = () => {};
const identity = (value: unknown) => value;
const Zone = {
    __symbol__: identity,
    assertZonePatched: noop,
    current: {
        fork: noop,
        get: identity,
    },
    fakeAsyncTest: {
        resetFakeAsyncZone: noop,
    },
};

// global.Zone has to exist as the testing modules access some functions directly instead of using the TestEnvironment dependency injection
Object.assign(global, {Zone});

const {NgZone, ɵNoopNgZone} = require('@angular/core');
const {getTestBed} = require('@angular/core/testing');
const {BrowserDynamicTestingModule, platformBrowserDynamicTesting} = require('@angular/platform-browser-dynamic/testing');

// NgZone has to be bend to noop as both core-testing and platform-browser-testing do `new core.NgZone` instead of using the TestEnvironment dependency injection
Object.assign(NgZone.prototype, ɵNoopNgZone.prototype);

getTestBed().initTestEnvironment(
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting([{provide: NgZone, useValue: new ɵNoopNgZone()}]),
);

We use jest as a test runner and native async/await. As jest isn't officially supported by zone.js, you have to use the patch from jest-preset-angular or bake your own. The above file renders that patch obsolete as the environment is untouched by zone.js. jest just runs as intended.

sod avatar Sep 23 '21 12:09 sod