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