ionic-team / ionic-team/ionic-unit-testing-example
Unit test within async using fixture.detectChanges() fails
- Dominant language
- TypeScript
- Stars
- 370
- Forks
- 144
- PR merge metrics
- No merged PRs in 30d
Description
Hello,
**This is the issue description:**
Using the method from `ComponentFixture` .`detectChanges()` is failing when you use it within an `async()` unit test.
**How to reproduce:**
1. Clone this repo: `git clone https://github.com/ionic-team/ionic-unit-testing-example.git`
2. Install packages: `cd ionic-unit-testing-example && sudo npm install`
3. Add the following unit test to the `src/app/app.component.spec.ts`:
```typescript
it( 'example test async with fixture.detectChanges()', async(() => {
fixture.detectChanges();
}));
```
4. Run tests: `npm run test-ci`
**After running the tests, it fails with the following error:**
```
..ERROR: 'Unhandled Promise rejection:', 'invalid link: Page1', '; Zone:', 'angular', '; Task:', 'Promise.then', '; Value:', 'invalid link: Page1', undefined
ERROR: 'Unhandled Promise rejection:', 'invalid link: Page1', '; Zone:', 'angular', '; Task:', 'Promise.then', '; Value:', 'invalid link: Page1', undefined
Chrome 65.0.3325 (Linux 0.0.0) MyApp Component example test async with fixture.detectChanges() FAILED
Failed: Uncaught (in promise): invalid link: Page1
Error: Uncaught (in promise): invalid link: Page1
at resolvePromise (webpack:///node_modules/zone.js/dist/zone.js:824:0 <- test-config/karma-test-shim.js:117151:31)
at Object.reject (webpack:///node_modules/zone.js/dist/zone.js:746:0 <- test-config/karma-test-shim.js:117073:17)
at NavControllerBase._fireError (webpack:///node_modules/ionic-angular/navigation/nav-controller-base.js:223:0 <- test-config/karma-test-shim.js:51342:16)
at NavControllerBase._failed (webpack:///node_modules/ionic-angular/navigation/nav-controller-base.js:216:0 <- test-config/karma-test-shim.js:51335:14)
at webpack:///node_modules/ionic-angular/navigation/nav-controller-base.js:263:44 <- test-config/karma-test-shim.js:51382:59
at ZoneDelegate.invoke (webpack:///node_modules/zone.js/dist/zone.js:392:0 <- test-config/karma-test-shim.js:116719:26)
............
```
**Expected result** should be at least not to throw this error when using `fixture.detectChanges()`.
The full `src/app/app.component.spec.ts` file would be as the following:
```typescript
import { async, TestBed, fakeAsync, ComponentFixture, tick } from '@angular/core/testing';
import { IonicModule, Platform, MenuController, Menu } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { MyApp } from './app.component';
import {
PlatformMock,
StatusBarMock,
SplashScreenMock
} from '../../test-config/mocks-ionic';
import { Page } from 'ionic-angular/navigation/nav-util';
import { By } from '@angular/platform-browser';
describe('MyApp Component', () => {
let fixture;
let component;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyApp],
imports: [
IonicModule.forRoot(MyApp)
],
providers: [
{ provide: StatusBar, useClass: StatusBarMock },
{ provide: SplashScreen, useClass: SplashScreenMock },
{ provide: Platform, useClass: PlatformMock }
]
});
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyApp);
component = fixture.componentInstance;
});
it('should be created', () => {
expect(component instanceof MyApp).toBe(true);
});
it('should have two pages', () => {
expect(component.pages.length).toBe(2);
});
it( 'example test async with fixture.detectChanges()', async(() => {
fixture.detectChanges();
}));
});
```
Doest anyone at least know why this could be happenning? I don't know if this could even be an Angular bug with lazy loading or whatever.
The only reference to `Page1` is inside `src/app/app.component.ts` in order to set up the page as the rootPage of the app:
```typescript
import { Component, ViewChild } from '@angular/core';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
import { Nav, Platform, Menu } from 'ionic-angular';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
@ViewChild(Nav) nav: Nav;
rootPage: any = 'Page1';
pages: Array<{ title: string, component: any }>;
constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen) {
// used for an example of ngFor and navigation
this.pages = [
{ title: 'Page One', component: 'Page1' },
{ title: 'Page Two', component: 'Page2' }
];
}
ionViewDidLoad() {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.nav.setRoot(page.component);
}
}
```
Thank you in advance.
Regards,
David.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.