This is my code in angular, the functionality is working all fine but the test cases are getting failed. Please tell me what i am doing wrong in the code? The error I am getting
HeadlessChrome 83.0.4103 (Windows 10.0.0) AboutComponent should create FAILED TypeError: Cannot read property 'getAboutInfo' of undefined at ** at AboutComponent.ngOnInit (http://localhost:9876/karma_webpack/src/app/about/about.component.ts:44:28) at callHook (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:3937:1) at callHooks (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:3901:1) at executeInitAndCheckHooks (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:3842:1) at refreshView (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11795:1) at renderComponentOrTemplate (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:11903:1) at tickRootContext (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:13379:1) at detectChangesInRootView (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:13413:1) at RootViewRef.detectChanges (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/core.js:15093:22) at ComponentFixture._tick (http://localhost:9876/karma_webpack/node_modules/@angular/core/ivy_ngcc/fesm2015/testing.js:323:1)
import { async, ComponentFixture, TestBed} from '@angular/core/testing';
import { AboutComponent } from './about.component';
import { AboutService } from './about.service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { Observable, of } from 'rxjs';
import { I18nService } from 'src/utils/i18n.service';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { AppModule } from './../app.module';
describe('AboutComponent', () => {
let component: AboutComponent;
let fixture: ComponentFixture<AboutComponent>;
let dialogSpy: jasmine.Spy;
let app: any;
const mockDialogRef = {
close: jasmine.createSpy('close')
};
let service: any;
const data = '20/04/2019';
let getAboutInfoSpy: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AboutComponent],
imports: [HttpClientTestingModule , AppModule],
providers: [{ provide: AboutService, useValue: service },
I18nService,
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: MatDialogRef, useValue: mockDialogRef}]
}).compileComponents();
}));
beforeEach(async () => {
fixture = TestBed.createComponent(AboutComponent);
component = fixture.componentInstance;
await fixture.whenStable();
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('infoList should be empty array', () => {
expect(app['dataList'].length).toBe(0);
});
it('when OnInit invoked through service data will return to infoList ', async(() => {
service = fixture.debugElement.injector.get(AboutService);
spyOn(service, 'getAboutInfo').and.returnValue(of(data));
app.ngOnInit();
expect(app['dataList'].length).toBe(3);
}));
it('onCancel should close the dialog', async( () => {
component.closePopup();
expect(mockDialogRef.close).toHaveBeenCalled();
}));
});
import { Component, OnInit, Inject } from '@angular/core';
import { AboutService } from './about.service';
import { Subscription } from 'rxjs';
import { MatDialogRef} from '@angular/material/dialog';
import { I18nService } from 'src/utils/i18n.service';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.scss']
})
export class AboutComponent implements OnInit {
private aboutServiceSubscription: Subscription;
dataList: any;
locales: any = {};
translator: any;
constructor(
private dialogRef: MatDialogRef<AboutComponent>,
public aboutService: AboutService,
private i18Service: I18nService) {}
ngOnInit() {
this.translator = this.i18Service.getTranslator();
this.translator.translateObject.subscribe((item: any) => {
this.locales = item;
});
this.aboutServiceSubscription = this.aboutService.getAboutInfo().subscribe((data: any) => {
if (data) {
data = data.split('/');
this.dataList = data;
}
});
}
/**
* Closes the poup
* @memberof AboutComponent
*/
closePopup() {
this.dialogRef.close();
}
}
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AboutService {
constructor(private http: HttpClient) {
}
getAboutInfo() {
return this.http.get('/assets/aboutInfo.txt', {responseType: 'text'})
}
}
providers: [{ provide: AboutService, useValue: service },
<= I don't see where you are instantiating a value for theservice
variable prior to the setup – Taplarservice = <something>
. Such asservice = jasmine.createObjectSpy('AboutService', ['getAboutInfo'])
. However, since the service isprovidedIn: 'root'
you shouldn't have to do that at all. You should just be able to remove that providers line and later useTestBed.inject(AboutService)
to get the service that was injected into your component. – Taplar