Skip to content

Instantly share code, notes, and snippets.

@paynoattn
Last active February 3, 2021 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paynoattn/1c8ac933892594701a9cb0c390494cc9 to your computer and use it in GitHub Desktop.
Save paynoattn/1c8ac933892594701a9cb0c390494cc9 to your computer and use it in GitHub Desktop.
Simple Observable testing in Angular2
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Data } from '../models';
@Injectable()
export class DataService {
dataUrl: string = 'data.json';
constructor ( http: Http ) { }
get(): Observable<Data[]> {
return this.http.get(this.dataUrl)
.map(this.extractData)
.catch(this.handleError)
}
// ...
private extractData(res: Response) {
let body = res.json();
return body || { };
}
private handleError(error: any) {
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : this.errorMsg;
console.error(error, errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
import { Observable } from 'rxjs/Observable';
import { Data, testData } from '../models';
export class DataStub {
public get(url: string): Observable<Data[]> {
return Observable.of(testData);
}
// ...
}
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Data } from '../models';
import { DataService } from '../services';
@Component {
selector: 'my-comp',
templateUrl: '/myComp/myComp.html'
}
export class MyComponent implements OnInit {
data: Data[];
constructor ( dataSvc : DataService ) { }
ngOnInit() {
this.dataSvc.get().subscribe(
data => this.data = data
);
}
}
import {
inject,
tick,
TestBed,
getTestBed,
async,
fakeAsync,
ComponentFixture
} from '@angular/core/testing';
import { Observable } from 'rxjs/Rx';
import { DataStub } from '../mocks';
import { testData } from '../models';
import { MyComponent } from './my.component';
import { DataService } from '../services';
let comp: MyComponent;
let fixture: ComponentFixture<MyComponent>;
let dataStub: Datastub;
describe('My Component', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MyComponent ]
}).overrideComponent(MyComponent, {
set: {
providers: [
{ provide: DataService, useClass: DataStub },
]
}
}).compileComponents()
.then(() => {
fixture = TestBed.createComponent(MyComponent);
comp = fixture.componentInstance;
dataStub = fixture.debugElement.injector.get(DataService);
});
}));
it('should resolve test data', fakeAsync(() => {
const spy = spyOn(dataStub, 'get').and.returnValue(
Observable.of(testData)
);
comp.ngOnInit();
fixture.detectChanges();
expect(comp.data).toEqual(testData);
expect(spy.calls.any()).toEqual(true);
}));
});
@elias-garcia
Copy link

This makes no sense.. Why are you calling spyOn in a service mock? If it's mocked, it's also returning a mock value, you don't need to return another mock value with the returnValue Jasmine function.

@davidsansay
Copy link

Awesome! thanks for sharing.

@alebo611
Copy link

alebo611 commented Feb 6, 2018

elias-garcia: Returning another mock value is very usefull when you need to test with different return values and not the same value all the time.

@guiworks
Copy link

guiworks commented Feb 3, 2021

How I test directly the data from arrow function? You are testing the this.data, but and If I want test directly the data? This is a dillema to me, I can't do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment