Jasmine-karma : how to check navigation functional

2019-03-04 07:26发布

问题:

I have written a test case for navController using spyOn, getting error called :

Error: <spyOn> : push() method does not exist
Usage: spyOn(<object>, <methodName>)

exp.ts :

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Injectable } from '@angular/core' ;
import { HttpClient, HttpResponse, HttpErrorResponse, HttpHeaders } from '@angular/common/http' ;
import { SubmittingHc } from '../submitting-conditions/submitting-conditions';

@Injectable()
@Component({
     selector: 'page-hc-entry',
     templateUrl: 'hc-entry.html'
})
export class HcEntryPage {

      private hc = {
        id: null,
        memberid: null,
        one:null,
        two:null
      };

      constructor(public navCtrl: NavController) {  }

      goToSubmittingConditions(){
        this.navCtrl.push(SubmittingHc, this.hc);
      }
}

exp.spec.ts :

 import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
 import { By } from '@angular/platform-browser';
 import { IonicModule, Platform, NavController} from 'ionic-angular/index';
 import { StatusBar } from '@ionic-native/status-bar';
 import { SplashScreen } from '@ionic-native/splash-screen';
 import { HcEntryPage } from './hc-entry';
 import { SubmittingHc } from '../submitting-conditions/submitting-conditions';

        describe('hc component' () => {
            let comp: HcEntryPage;
            let fixture: ComponentFixture<HcEntryPage>;

            beforeEach(async(()=>{
                TestBed.configureTestingModule({
                    declarations:[HcEntryPage],
                    imports:[
                        IonicModule.forRoot(HcEntryPage)
                    ],
                    providers:[
                        NavController,
                        SubmittingHc
                    ]
                });
            }));
            beforeEach(()=>{
                fixture = TestBed.createComponent(HcEntryPage);
                comp = fixture.componentInstance;
            });

            it('should create component', () => expect(comp).toBeDefined());

            it('should navigate to submitting condition page', () =>{
                spyOn(comp.navCtrl, 'push').and.stub();
                comp.goToSubmittingConditions();
                expect(comp.navCtrl.push).toHaveBeenCalledWith(SubmittingHc);
            });
        });

Tried the below code but gives same error :

it('should be able to launch SubmittingHc page', () => {

        let navCtrl = fixture.debugElement.injector.get(NavController);
        spyOn(navCtrl, 'push');
        comp.goToMyCare({});
        expect(navCtrl.push).toHaveBeenCalledWith(SubmittingHc);

    });

回答1:

Try making a file "project/test-config/mocks-ionic.ts" containing:

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;
    }

    public registerChildNav(nav: any): void {
        return ;
    }
}

Now import NavMock and redefine providers like:

import {
  NavMock
} from '../test-config/mocks-ionic'

providers: [
    { provide: NavController, useClass: NavMock}
  ]

Example test case:

it('should be able to launch wishlist page', () => {

    let navCtrl = fixture.debugElement.injector.get(NavController);
    spyOn(navCtrl, 'push');

    de = fixture.debugElement.query(By.css('ion-buttons button'));

    de.triggerEventHandler('click', null);

    expect(navCtrl.push).toHaveBeenCalledWith(WishlistPage);

});

Refer to this project for more help: https://github.com/ionic-team/ionic-unit-testing-example