Hi there,
I’ve implemented the testing environment documented here and can get basic unit tests working. However when I’m wanting to test modals or anything more complicated, I get a whole bunch of errors. So I’m wondering is unit testing not ready in Ionic 2 or am I doing something wrong?
The main issue I’m having at the moment is when trying to test whether a modal is being called, I get errors along the lines of
Error: Error in ./LoginPage class LoginPage - inline template:8:110 caused by: Cannot read property 'present' of undefined
Even though I have mocked the ModalController. I’ve tried mocking practically everything (purely to find out where the issue is because the unit test with mocks for everything is practically useless) but I still get the error.
Here is the code:
import { TestBed, ComponentFixture, async } from '@angular/core/testing';
import {} from 'jasmine'
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { IonicModule, NavController, ToastController, LoadingController, ModalController, NavParams, ViewController } from 'ionic-angular';
import { Storage } from '@ionic/storage';
import { MyApp } from '../../app/app.component';
import { LoginPage, HostnamePage } from '../pages';
import { User } from '../../models/user';
import { UserService } from '../../providers/user.service';
import { NavParamsMock, StorageMock, UserServiceMock, ViewControllerMock, ModalControllerMock, ToastControllerMock, LoadingControllerMock } from '../../mocks'
let comp: LoginPage;
let fixture: ComponentFixture<LoginPage>;
let de: DebugElement;
let el: HTMLElement;
describe('Page: Login', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyApp, LoginPage, HostnamePage],
providers: [
NavController,
{
provide: LoadingController,
useClass: LoadingControllerMock
},
{
provide: ModalController,
useClass: ModalControllerMock
},
{
provide: NavParams,
useClass: NavParamsMock
},
{
provide: Storage,
useClass: StorageMock
},
{
provide: UserService,
useClass: UserServiceMock
},
{
provide: ViewController,
useClass: ViewControllerMock
},
{
provide: ToastController,
useClass: ToastControllerMock
}
],
imports: [
IonicModule.forRoot(MyApp)
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginPage);
comp = fixture.componentInstance;
});
afterEach(() => {
fixture.destroy();
comp = null;
de = null;
el = null;
});
it('is created', () => {
expect(fixture).toBeTruthy();
expect(comp).toBeTruthy();
});
it('changeUrl function creates hostname modal', () => {
fixture.detectChanges();
comp.changeUrl();
let de = fixture.debugElement.query(By.css('.sectionHeading'));
expect(de).toBe('Change Hostname');
});
});
I’ve also tried something like this:
it(‘changeUrl function creates hostname modal’, () => {
const element = fixture.debugElement.query(By.css("#changeURL"));
element.triggerEventHandler(‘click’, null);
}
From login.html:
<div id="changeURL" text-right style="padding-top: 41px; word-wrap: normal; text-overflow: ellipsis;" (click)="changeUrl()">
<span ion-text color="primary">{{hostname}}</span>
</div>
From login.ts
changeUrl(){
let login = {
userDefinedHostname: this.userDefinedHostname,
username: this.username,
password: this.password,
buildIdentifier: this.buildIdentifier
}
let modal = this.modalCtrl.create(HostnamePage, {defaultHostname: this.defaultHostname, login: login});
modal.present();
}
From mocks.ts
export class ViewControllerMock {
public _setHeader(): any { return {} };
public _setNavbar(): any { return {} };
public _setIONContent(): any { return {} };
public _setIONContentRef(): any { return {} };
}
export class ModalControllerMock extends ViewControllerMock {
public present(): any { return };
public create(param): any { return };
}
Any help would be greatly appreciated. As it stands, I can’t really unit test anything of worth.