After diving into integration testing, the whole process seems quite perplexing to me.
In my initial attempt, it appears that my spy is not returning the data as expected. The error states: Expected 0 to be 3. It would be immensely helpful if someone could guide me on where I might be going wrong.
Below are my service, page, spec files along with the template:
MyService
import { Data } from './../data/data.model';
import { Injectable } from '@angular/core';
import { BehaviorSubject, of } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class MyService {
private _data = new BehaviorSubject<Data[]>([]);
get data() {
return this._data;
}
constructor() {}
getAllData() {
return of([
{
id: '1',
title: 'Rice',
},
{
id: '2',
title: 'Wheat',
},
{
id: '33',
title: 'Water',
},
]).pipe(
tap((data) => {
this._data.next(data);
})
);
}
}
DataPage Component
import { Component, OnInit } from '@angular/core';
import { BehaviorSubject, Observable, of, Subscription } from 'rxjs';
import { MyService } from '../services/my.service';
import { Data } from './data.model';
@Component({
selector: 'app-data',
templateUrl: './data.page.html',
styleUrls: ['./data.page.scss'],
})
export class DataPage implements OnInit {
allData: Data[];
dataServiceSub: Subscription;
isLoading: boolean;
constructor(private myService: MyService) {}
ngOnInit() {
this.dataServiceSub = this.myService.data.subscribe(
(data) => {
console.log(data);
this.allData = data;
}
);
}
ngOnDestroy() {
if (this.dataServiceSub) {
console.log('ngOnDestroy');
this.dataServiceSub.unsubscribe();
}
}
ionViewWillEnter() {
this.isLoading = true;
this.myService.getAllData().subscribe(() => {
console.log('ionViewWillEnter');
this.isLoading = false;
});
}
}
DataPage.spec
import { MyService } from '../services/my.service';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';
import { DataPage } from './data.page';
import { of } from 'rxjs';
describe('DataPage', () => {
let component: DataPage;
let fixture: ComponentFixture<DataPage>;
let serviceSpy: jasmine.SpyObj<MyService>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DataPage],
providers: [
{
provide: MyService,
useClass: MyService
},
],
imports: [IonicModule.forRoot()],
}).compileComponents();
fixture = TestBed.createComponent(DataPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
fit('Should show list of data if data is available', () => {
serviceSpy = TestBed.get(MyService);
spyOn(serviceSpy, 'getAllData').and.returnValue(of([
{
id: '1',
title: 'Rice',
},
{
id: '2',
title: 'Wheat',
},
{
id: '33',
title: 'Water',
},
]));
fixture.detectChanges();
const element = fixture.nativeElement.querySelectorAll(
'[test-tag="dataList"] ion-item'
);
console.log(
fixture.nativeElement.querySelectorAll('[test-tag="dataList"]')
);
expect(element.length).toBe(3);
});
});
HTML
<ion-content>
<div test-tag="empty" class="ion-text-center">
<ion-text color="danger">
<h1>No data</h1>
</ion-text>
</div>
<div test-tag="dataList">
<ion-list>
<ion-item *ngFor="let data of allData">
<ion-label test-tag="title">{{data.title}}</ion-label>
</ion-item>
</ion-list>
</div>
</ion-content>