angular: "Navigation triggered outside Angular zone" warning in unit tests
I’m submitting a…
[x] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:
Current behavior
Using the last Angular 6.1.7
which introduced a warning if a navigation is triggered outside a zone (see https://github.com/angular/angular/commit/010e35d99596e1b35808aaaeecfc32f3b247a7d8),
a simple unit test calling router.navigate
yields the warning (resulting in hundreds of warnings in the console).
Expected behavior
The warning should not be emitted in unit tests.
It’s currently possible to remove it by using zone.run
or using NoopNgZone
, but this is cumbersome. A way to disable it in unit tests would be great.
Minimal reproduction of the problem with instructions
Build a minimal app with the CLI
ng new router-warning --routing
Then replace the default unit test with:
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should create the app', async(() => {
const router = TestBed.get(Router) as Router;
router.navigateByUrl('/');
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
});
Run ng test
, and the following warning should appear:
WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?'
Environment
Angular version: 6.1.7 or 7.0.0-beta.5
Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 8.11.3
- Platform: Mac
cc @trotyl
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 127
- Comments: 34 (6 by maintainers)
Links to this issue
Commits related to this issue
- fix(router): better ngZone checking for warning Closes #25837 — committed to trotyl/angular by trotyl 6 years ago
- /3/login test navigation after login. could not mock ActivatedRoute so testing with Router See also https://github.com/angular/angular/issues/25837 — committed to AndrejSzasz/SportsBook by deleted user 6 years ago
- Note and report known Angular testing issue 'Possible issue: https://github.com/angular/angular/issues/25837' — committed to LinguaTechnica/herobook by deleted user 5 years ago
- Reduce unit test noise WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?' This was being generated by the following components: - ClientRunsComponent - Servi... — committed to chef/automate by msorens 5 years ago
- Reduce unit test noise WARN: 'Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?' This was being generated by the following components: - ClientRunsComponent - Servi... — committed to chef/automate by msorens 5 years ago
- [automate-1640] Automate-ui version bump from Angular 6 -> Angu… (#1707) * Remove incompatible npm package Attempts to upgrade Angular reported that the "ngrx-tslint-oftype" package was not compa... — committed to chef/automate by msorens 5 years ago
- fix(router): better ngZone checking for warning Do not warn that navigation was triggered outside Angular zone if the Router was created outside Angular zone in the first place. Closes #25837 — committed to trotyl/angular by trotyl 6 years ago
- fix(router): better ngZone checking for warning (#25839) Do not warn that navigation was triggered outside Angular zone if the Router was created outside Angular zone in the first place. Closes #258... — committed to angular/angular by trotyl 6 years ago
Workaround:
In unit test:
I’d say you don’t need to navigate in unit tests. You should spy on those methods and assert that they have been called.
You also need to wrap router.initialNavigation();
Workround proposed by @ItzhakBokris worked, but it must not be a permanent solution. Waiting to angular team!
this.ngZone.run(() => this.router.navigate(['home'])).then();
+1
As a workaround for tests, I created small proxy that runs all methods of router within NgZone.
Note:
unknown
is replacement forany
in TypeScript 3.0.Usage:
For unit tests, yes. But the same framework can also be used for integration tests where you should be able to instantiate routing and do navigation.
I’ve also run into this in tests, and the workaround proposed by @piotrl doesn’t work for me as some navigations are triggered by the tested code, also causing these warnings – since that is what I am testing I don’t want to mock everything here.
My approach is thus to instead silence the particular warning:
and then
I see this warning in the console when running my app normally, not in unit tests.
That’s all , thank you! No errors, No warnings. very good! 😄
I guess It is because latest angular CLI creates routing in a separate module app-routing.module.ts
so to run navigation with in Angular zone it is required to implement work around -
Alternatively if you define routing with in app module, it works fine. app.routing.ts
+1
I also received the same warning by using ngrx/effects:
nice workaround!
@trotyl, yeah, several other issues have the same problems, in
test
,NgZone.isInAngularZone()
will befalse
, we may need aTestNgZone
to work withComponentFixture.autoDetectChanges
I am getting this in my actual code. Not just in the tests.
this.router.navigate([this.returnUrl])
I usually do this,
this ensures that navigation is performed inside ngZone. thanks to @fpellanda
I tried this workaround to avoid the warning:
I suggest as workaround to run
navigate
infixture.ngZone
with a spy:Please open a new issue with minimal reproduction if you’re encountering this outside testing.
@quirogamauricio It’s the expected warning, when perform navigation outside Angular zone than no change detection will be triggered. You do can perform navigation from anywhere of the JavaScript engine, but just need to ensure it inside Angular zone.