unitarios unitarias unit test pruebas javascript unit-testing angular ionic2 karma-jasmine

javascript - test - pruebas unitarias jasmine



No se puede leer la propiedad ''_getPortal'' de undefined en iónico 2 Unit testing (2)

Soy un principiante en la prueba de unidades iónicas. Seguí la documentación angular 2 ( https://angular.io/docs/ts/latest/guide/testing.html ) para probar mi aplicación iónica 2 con karma y jazmín.

Pero ahora estoy atrapado en un error llamado

''No se puede leer la propiedad'' _getPortal ''de undefined''

aquí está mi archivo LocationSearchModal.ts

import { Component } from ''@angular/core''; import { NavController, ViewController } from ''ionic-angular''; import { Location } from ''../../services/domain/Location''; import { LocationService } from ''../../services/LocationService''; import { LoadingController } from ''ionic-angular''; @Component({ selector: ''location-search-modal'', templateUrl: ''location-search-modal.html'' }) export class LocationSearchModal { locationList: Array<Location> = new Array<Location>(); selectedLocation: number; temp: any = "test"; constructor(public navCtrl: NavController, public locationService: LocationService, public viewController: ViewController, public loadingController: LoadingController) { this.filterLocationsForString(); } filterLocations(event: any): void { const searchString: string = event.target.value; this.filterLocationsForString(searchString); console.log(this.filterLocationsForString(searchString)); } filterLocationsForString(searchString?: string) { let loader = this.loadingController.create({ content: "loading" }); loader.present(); this.locationService.getLocationsForLikeSearchString(searchString) .subscribe((result) => { loader.dismissAll(); this.locationList = result }); console.log(this.locationList); } closeLocationSearch() { this.locationService.getLocationById(this.selectedLocation) .subscribe((location) => this.viewController.dismiss(location[0])); } }

y usé el servicio llamado locationService.ts allí y este es ese servicio

import { Injectable } from ''@angular/core''; import { Location } from ''./domain/Location''; import { DatabaseAccessor } from ''../database/DatabaseAccessor''; import { Observable } from ''rxjs/Rx''; @Injectable() export class LocationService { locationList:Array<Location> = new Array<Location>(); constructor(public databaseAccessor: DatabaseAccessor) {} getLocationsForLikeSearchString(searchString: string) : Observable<Array<Location>> { const searchValue = (searchString == null) ? ''%'' : searchString.trim() + ''%''; return <Observable<Array<Location>>> Observable.fromPromise(this.databaseAccessor.runSelectQuery(Location, new Location(), ''WHERE name LIKE ?'', [searchValue])); } getLocationById(id: number): Observable<Location> { return <Observable<Location>> Observable.fromPromise(this.databaseAccessor.runSelectQuery(Location, new Location(), ''WHERE id = ?'', [id])); } saveLocations(locations: Array<Location>){ this.databaseAccessor.runInsertBatchQuery(Location.prototype, locations); } }

Finalmente, escribí un archivo spec.ts para pruebas unitarias y aquí está eso,

import { ComponentFixture, async } from ''@angular/core/testing''; import { LocationSearchModal } from ''./LocationSearchModal''; import { LocationService } from ''../../services/LocationService''; import { TestUtils } from ''../../test''; import { TestBed } from ''@angular/core/testing''; import { App, NavController, Platform, Config, Keyboard, Form, IonicModule, GestureController, ViewController, LoadingController } from ''ionic-angular''; import { ConfigMock } from ''../../mocks''; import { TranslateModule } from ''ng2-translate''; import { DatabaseAccessor } from ''../../database/DatabaseAccessor''; let comp: LocationSearchModal; let fixture: ComponentFixture<LocationSearchModal>; let instance: any = null; describe(''LocationSearchModal'', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [LocationSearchModal], // declare the test component providers: [App, Platform, Form, Keyboard, NavController, GestureController, LoadingController, LocationService, DatabaseAccessor, { provide: ViewController, useClass: class { ViewController = jasmine.createSpy("viewController"); } }, { provide: Config, useClass: ConfigMock }, ], imports: [ IonicModule, TranslateModule.forRoot(), ], }); fixture = TestBed.createComponent(LocationSearchModal); comp = fixture.componentInstance; })); console.log(comp); it(''Testing Location Component'', () => { expect(comp.temp).toBe(''test''); }) });

cuando estoy corriendo, el siguiente error proviene de la terminal. (La configuración de prueba de mi unidad es correcta y la probé con otro archivo .spec.ts simple)

el error

SUMMARY: ✔ 1 test completed ✖ 1 test failed FAILED TESTS: LocationSearchModal ✖ Testing Location Component Chrome 54.0.2840 (Linux 0.0.0) Failed: Error in ./LocationSearchModal class LocationSearchModal_Host - inline template:0:0 caused by: Cannot read property ''_getPortal'' of undefined TypeError: Cannot read property ''_getPortal'' of undefined at App.present (webpack:/media/dilanka/Stuff/CODE%20BASE/Inspection/Unit%20Testing/Inspection-Rewrite/~/ionic-angular/components/app/app.js:78:0 <- src/test.ts:2091:35) at Loading.present (webpack:/media/dilanka/Stuff/CODE%20BASE/Inspection/Unit%20Testing/Inspection-Rewrite/~/ionic-angular/components/loading/loading.js:31:0 <- src/test.ts:38779:26) at LocationSearchModal.filterLocationsForString (webpack:/media/dilanka/Stuff/CODE%20BASE/Inspection/Unit%20Testing/Inspection-Rewrite/src/pages/location-search/LocationSearchModal.ts:9:4184 <- src/test.ts:18993:4170) at new LocationSearchModal (webpack:/media/dilanka/Stuff/CODE%20BASE/Inspection/Unit%20Testing/Inspection-Rewrite/src/pages/location-search/LocationSearchModal.ts:9:3407 <- src/test.ts:18993:3391) at new Wrapper_LocationSearchModal (/DynamicTestModule/LocationSearchModal/wrapper.ngfactory.js:7:18) at _View_LocationSearchModal_Host0.createInternal (/DynamicTestModule/LocationSearchModal/host.ngfactory.js:16:35) at _View_LocationSearchModal_Host0.AppView.create (webpack:/media/dilanka/Stuff/CODE%20BASE/Inspection/Unit%20Testing/Inspection-Rewrite/~/@angular/core/src/linker/view.js:84:0 <- src/test.ts:52350:21) at _View_LocationSearchModal_Host0.DebugAppView.create (webpack:/media/dilanka/Stuff/CODE%20BASE/Inspection/Unit%20Testing/Inspection-Rewrite/~/@angular/core/src/linker/view.js:294:0 <- src/test.ts:52560:44) at ComponentFactory.create (webpack:/media/dilanka/Stuff/CODE%20BASE/Inspection/Unit%20Testing/Inspection-Rewrite/~/@angular/core/src/linker/component_factory.js:152:0 <- src/test.ts:32035:36) at initComponent (webpack:/media/dilanka/Stuff/CODE%20BASE/Inspection/Unit%20Testing/Inspection-Rewrite/~/@angular/core/bundles/core-testing.umd.js:855:0 <- src/test.ts:7416:53)


Resolví este problema finalmente. Usé un simulacro y definí los métodos requeridos en ese simulacro. Entonces funciona :)
aquí hay un ejemplo para un simulacro.

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

entonces tiene que importar ese simulacro en su archivo .spec.ts la siguiente manera

import {ViewControllerMock} from ''../../mocks'';

entonces tiene que definir ese simulacro en sus proveedores en el archivo spec.ts la siguiente manera

providers: [{ provide: ViewController, useClass: ViewControllerMock}],


LoadingController si el problema es al usar LoadingController

export class LoadingControllerMock { _getPortal(): any { return {} }; create(options?: any) { return new LoadingMock() }; } class LoadingMock { present() { }; dismiss() { }; dismissAll() { }; }

Importa el simulacro y el real desde cualquier lugar

import { LoadingController } from ''ionic-angular''; import { LoadingControllerMock } from ''../../../../test-config/mocks-ionic'';

Sustituir

providers: [ { provide: LoadingController, useClass: LoadingControllerMock } ]