Issue
I'm writing unit tests for an Angular application to test frontend functionality and am trying to generate a way to mock a rest service call for the following scenario:
I have a class defined as follows:
import { Component, OnInit } from '@angular/core';
import {RestService} from "../../../../../services/rest.service";
import {ActivatedRoute, Router} from "@angular/router";
@Component({
selector: 'app-example-class',
templateUrl: './example-class.component.html',
styleUrls: ['./example-class.component.scss']
})
export class ExampleClass implements OnInit {
myData: any = [];
reloadInterval: any;
constructor(private rest: RestService) {
this.reloadInterval = setInterval(() => {
this.getData();
}, 10000);
}
ngOnInit() {
this.getData();
}
ngOnDestroy(){
clearInterval(this.reloadInterval);
}
getData() {
this.rest.call(‘exampleClass’, this.rest.id).subscribe((data: {}) => {
if (data['rows']) {
this.myData = data['rows'].reduce((accumulator, currRow)=> accumulator + currRow.value, 0);
}
});
}
}
I want to specifically test my "getData()" method using Karma/Jasmine unit testing framework. Here's what I've created:
describe('ExampleClassComponent', () => {
let component: ExampleClass;
let fixture: ComponentFixture<ExampleClass>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
],
declarations: [ ExampleClass ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExampleClass);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create',
inject(
[HttpTestingController],
(httpMock: HttpTestingController) => {
expect(component).toBeTruthy();
}));
});
This works. The component gets created and the test passes. However, when I try to do the following:
it('should test number of elements', ()=>{
component.getData();
expect(component.myData.length).toBe(1);
});
This fails. And it fails because it's trying to call the getData() method with a rest call to a service that's not running. I want to somehow mock the rest call made in that function. I've tried creating a MockRestService class in my test class as such:
class MockRestService extends RestService {
myData = [
{myData: 1}
];
call(endpoint: string, params?: Object, data?: any, queryString?: string, isCustomUri?: boolean): Observable<any> {
return of(this.myData);
}
}
and then modifying my test:
it('should test number of elements', ()=>{
let mockRestService = new MockRestService(null);
component = new ExampleClass(mockRestService);
component.getData();
expect(component.myData.length).toBe(1);
});
But this doesn't work. Is it possible to mock the rest call made in getData for the purposes of testing, and if so how? I really appreciate the help!
Solution
You don't need separate MockRestService
class but can use Jasmine's spyOn
to mock the RestService.call
method. This could look as follows.
it('should test number of elements', ()=> {
// given
const restService = TestBed.inject(RestService);
const data = {} // define your rest call data
spyOn(restService, 'call').and.returnValue(of(data));
// when
component.getData();
// then
expect(component.myData.length).toBe(1);
});
Answered By - uminder
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.