我已根据Josh Morony's TDD tutorial创建了一个Ionic2项目。我使用的是左侧菜单(在应用模块中定义),因此我尝试在菜单中的链接上编写测试。
不幸的是,我收到的错误是我无法弄清楚的。它似乎与NavController有关,所以也许我需要改变我嘲笑它的方式。我应该使用mockNavController
from the Ionic library吗?来自mockNavController
的{{1}}似乎没有帮助......
错误由../../node_modules/ionic-angular/util/mock-providers
触发。我在下面的块中删除了一些代码,但我认为我包含了与错误相关的所有内容。
app.component.spec.ts
fixture.detectChanges()
mocks.ts
import { async, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { IonicModule, Platform, NavController } from 'ionic-angular';
import { NavMock, StatusBarMock, SplashScreenMock } from '../mocks';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { MyApp } from './app.component';
import { PlatformMock } from '../../test-config/mocks-ionic';
import { HomePage } from '../pages/home/home';
describe('MyApp Component', () => {
let fixture;
let component;
let de: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
MyApp,
HomePage
],
imports: [
IonicModule.forRoot(MyApp)
],
providers: [
{ provide: NavController, useClass: NavMock },
{ provide: StatusBar, useClass: StatusBarMock },
{ provide: SplashScreen, useClass: SplashScreenMock },
{ provide: Platform, useClass: PlatformMock },
OverlayService
]
})
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyApp);
component = fixture.componentInstance;
});
it ('should be created', () => {
expect(component instanceof MyApp).toBe(true);
});
it('displays the home page to the user', () => {
expect(component['rootPage']).toBe(HomePage);
});
it('links to the pages in the menu', () => {
let navCtrl = fixture.debugElement.injector.get(NavController);
spyOn(navCtrl, 'setRoot');
fixture.detectChanges();
de = fixture.debugElement.query(By.css('#menu-content ion-list button'));
de[0].triggerEventHandler('click', null);
expect(navCtrl.setRoot).toHaveBeenCalledWith(HomePage, {});
});
});
app.component.ts
export class NavMock {
public pop(): any {
return new Promise(function(resolve: Function): void {
resolve();
});
}
public push(): any {
return new Promise(function(resolve: Function): void {
resolve();
});
}
public getActive(): any {
return {
'instance': {
'model': 'something',
},
};
}
public setRoot(): any {
return true;
}
// ADDED TO PUSH FORWARD THIS TEST PAST A PREVIOUS ERROR
public registerChildNav(): any {
return true;
}
// ADDED TO TRY AND FIX THIS ERROR
public _config: any = {
plt: {
isRTL: function() {return true;}
}
}
}
export class PlatformMock {
public ready(): any {
return new Promise((resolve: Function) => {
resolve();
});
}
}
export class StatusBarMock {
public styleDefault(): any {
return true;
}
}
export class SplashScreenMock {
public hide(): any {
return true;
}
}
app.html
import { Component, ViewChild } from '@angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { HomePage } from '../pages/home/home';
@Component({
templateUrl: 'app.html',
entryComponents: [
HomePage
]
})
export class MyApp {
@ViewChild(Nav) nav: Nav;
rootPage: any = HomePage;
pages: Array<{title: string, component: any}>;
constructor(public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen) {
this.initializeApp();
// used for an example of ngFor and navigation
this.pages = [
{ title: 'Home', component: HomePage }
];
}
initializeApp() {
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);
}
}
测试控制台中显示的错误:
<ion-menu [content]="content">
<ion-header>
<ion-toolbar color="dark">
<ion-title>MyApp</ion-title>
</ion-toolbar>
</ion-header>
<ion-content id="menu-content">
<ion-list>
<button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>