2016-11-29 81 views
2

mIve得到了以下單元測試,測試了我用Ionic 2編寫的組件。單元測試給出了Ionic庫中的一個錯誤,我假設我沒有正確地模擬它或作爲Ionic 2 ViewController單元測試

import { ComponentFixture, async } from '@angular/core/testing'; 
import { TestUtils }    from '../../test'; 
import {} from 'jasmine'; 

import { LocationSearchModal } from './LocationSearchModal'; 
import { LocationService } from '../../services/LocationService'; 
import { PouchDbService } from '../../services/common/PouchDbService'; 

import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 
import { TestBed } from '@angular/core/testing'; 
import { App, MenuController, NavController, Platform, Config, Keyboard, Form, IonicModule, ViewController, GestureController, NavParams } from 'ionic-angular'; 
import { ConfigMock } from '../../mocks'; 
import { TranslateModule } from 'ng2-translate'; 
import { LoadingController } from 'ionic-angular'; 

let fixture: ComponentFixture<LocationSearchModal> = null; 
let instance: any = null; 

describe('LocationSearchModal',() => { 
    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ 
     LocationSearchModal 
     ], 
     providers: [ 
     App, Platform, Form, Keyboard, MenuController, NavController, GestureController, LocationService, LoadingController, 
     { provide: ViewController, useClass: class { ViewController = jasmine.createSpy("viewController"); } }, 
     { provide: NavParams, useClass: class { NavParams = jasmine.createSpy("navParams"); } }, 
     { provide: PouchDbService, useClass: class { PouchDbService = jasmine.createSpy("pouchDbService"); } }, 
     {provide: Config, useClass: ConfigMock} 
     ], 
     imports: [ 
     FormsModule, 
     IonicModule, 
     ReactiveFormsModule, 
     TranslateModule.forRoot(), 
     ], 
    }) 
    .compileComponents() 
    .then(() => { 
     fixture = TestBed.createComponent(LocationSearchModal); 
     instance = fixture.debugElement.componentInstance; 
     fixture.autoDetectChanges(true); 
    }); 
    })); 

    afterEach(() => { 
    fixture.destroy(); 
    }); 

    it('loads',() => { 
    expect(fixture).not.toBeNull(); 
    expect(instance).not.toBeNull(); 
    }) 
}) 

這是使用正在測試的組件的ViewController的相關摘錄。

this.locationService.getLocationById(this.selectedLocation) 
     .subscribe((location: any) => { 
     this.viewController.dismiss(location.doc) 
     }); 

測試失敗,我得到了下面的堆棧跟蹤

Chrome 53.0.2785 (Linux 0.0.0) 
TypeError: viewCtrl._setHeader is not a function 
    at new Header (webpack:///home/milinda/workspaces/eclipse/inspection/addedinspection/Inspection-Upgrade/~/ionic-angular/components/toolbar/toolbar.js:14:0 <- src/test.ts:11833:30) 
    at new Wrapper_Header (/IonicModule/Header/wrapper.ngfactory.js:7:18) 

這關係到我已經創建了一個茉莉花間諜爲

{ provide: ViewController, useClass: class { ViewController = jasmine.createSpy("viewController"); } },

有後ViewController線看看代碼庫我在這裏找到了_setHeader方法

https://github.com/driftyco/ionic/blob/6b3e2ed447340cdd35c328c96aa7cfa5f34eb214/src/navigation/view-controller.ts#L364

我也試過編寫自定義提供程序,但也得到了相同的錯誤。任何關於什麼是測試ViewController的正確方法的想法。

此外,有時解決問題的ViewController後可以從NavParams也許

回答

9

建立在Marky Sparky的答案上。由於離子3+:

export class ViewControllerMock{ 
    readReady = { 
    subscribe(){ 

    } 
    }; 
    writeReady = { 
    subscribe(){ 

    } 
    }; 

    dismiss(){ 
    console.log('View Controller Dismiss Called'); 
    } 
    _setHeader(){ 

    } 
    _setNavbar(){ 

    } 
    _setIONContent(){ 

    } 
    _setIONContentRef(){ 

    } 
} 

版本上工作:

Cordova CLI: 6.5.0 
Ionic Framework Version: 3.0.1 
Ionic CLI Version: 3.0.0-beta7 
ios-deploy version: 1.9.1 
ios-sim version: Not installed 
OS: macOS Sierra 
Node Version: v7.8.0 
Xcode version: Xcode 8.3.2 Build version 8E2002 
+2

來自於yesotung,在離子模擬中也有內建:來自「ionic-angular/util/mock-providers」的import {mockApp,mockConfig,mockPlatform,mockView};並使用它像{提供:ViewController,useValue:mockView()}, – eesdil

3

在單元測試中提到的ViewController當我有同樣的問題出現的問題。我剛剛解決了它。 像這樣創建

class ViewControllerMock { 
    public _setHeader(): any { 
    return {} 
    }; 
    public _setIONContent(): any { 
    return {} 
    }; 
    public _setIONContentRef(): any { 
    return {} 
    }; 
} 

一個模擬然後在調用添加到您的供應商TestBed.configureTestingModule這樣的:

TestBed.configureTestingModule({ 
    declarations: [ 
    ...components, 
    OrdinalPipe, 
    IgnoreNulls 
    ], 
    providers: [ 
    NavController, 
    ChartsService, FundsService, Utils, BlogService 
    , Payment, PlanHelper, Storage, PalIdle, SimpleExpiry, ContentService, PlansService, 
    App, Platform, Form, Keyboard, MenuController, 
    { provide: ModalController, useClass: ModalControllerMock }, 
    { provide: ViewController, useClass: ViewControllerMock }, 
    { provide: Config, useClass: ConfigMock } 
    ], 
    imports: [ 
    FormsModule, 
    IonicModule, 
    ReactiveFormsModule, 
    ], 
}) 

這爲我工作,當我有viewCtrl._setHeader不是功能錯誤今天提前。希望能幫助到你。

+0

新的Ionic 2.0 FINAL打破了這個模擬。具體而言,這些函數調用this._viewCtrlReadSub = viewCtrl.readReady.subscribe(function(){ _this._viewCtrlReadSub.unsubscribe(); _this._readDimensions(); }); –

0

接受的答案並沒有爲離子版本3.9.2工作,但是下面固定的問題:

export class ViewControllerMock { 

    public readReady: any = { 
    emit(): void { 

    }, 
    subscribe(): any { 

    } 
    }; 

    public writeReady: any = { 
    emit(): void { 

    }, 
    subscribe(): any { 

    } 
    }; 

    public contentRef(): any { 
    return new Promise(function (resolve: Function): void { 
     resolve(); 
    }); 
    } 

    public didEnter(): any { 
    return new Promise(function (resolve: Function): void { 
     resolve(); 
    }); 
    } 

    public didLeave(): any { 
    return new Promise(function (resolve: Function): void { 
     resolve(); 
    }); 
    } 

    public onDidDismiss(): any { 
    return new Promise(function (resolve: Function): void { 
     resolve(); 
    }); 
    } 

    public onWillDismiss(): any { 
    return new Promise(function (resolve: Function): void { 
     resolve(); 
    }); 
    } 

    public willEnter(): any { 
    return new Promise(function (resolve: Function): void { 
     resolve(); 
    }); 
    } 

    public willLeave(): any { 
    return new Promise(function (resolve: Function): void { 
     resolve(); 
    }); 
    } 

    public willUnload(): any { 
    return new Promise(function (resolve: Function): void { 
     resolve(); 
    }); 
    } 

    public dismiss(): any { 
    return true; 
    } 

    public enableBack(): any { 
    return true; 
    } 

    public getContent(): any { 
    return true; 
    } 

    public hasNavbar(): any { 
    return true; 
    } 

    public index(): any { 
    return true; 
    } 

    public isFirst(): any { 
    return true; 
    } 

    public isLast(): any { 
    return true; 
    } 

    public pageRef(): any { 
    return true; 
    } 

    public setBackButtonText(): any { 
    return true; 
    } 

    public showBackButton(): any { 
    return true; 
    } 

    public _setHeader(): any { 
    return true; 
    } 

    public _setIONContent(): any { 
    return true; 
    } 

    public _setIONContentRef(): any { 
    return true; 
    } 

    public _setNavbar(): any { 
    return true; 
    } 

    public _setContent(): any { 
    return true; 
    } 

    public _setContentRef(): any { 
    return true; 
    } 

    public _setFooter(): any { 
    return true; 
    } 

} 

Ionic Info

cli packages: 

    @ionic/cli-plugin-proxy : 1.5.6 
    @ionic/cli-utils  : 1.14.0 
    ionic (Ionic CLI)  : 3.14.0 

local packages: 

    @ionic/app-scripts : 3.1.0 
    Ionic Framework : ionic-angular 3.9.2