I've recently built an application that works and I'm trying to build a test. My service fetches items from an API backend:
export class CatfactService { constructor(private http: Http) {} getFacts() { const url = "http://www.catfact.info/api/v1/facts.json"; return this.http.get(url).map(this.extractData) .catch(this.handleError); }
Inside my component I'm able to subscribe to the API response. The result of the facts
variable is the response details from the API:
ngOnInit() { this.counter = this.start; this.service.getFacts().subscribe((facts) => { this.results = facts.facts; }); }
Now, I'm building a test for the service, and strangely the subscribe method gets the argument, but rather than the argument being the response data, it returns a promise that ultimately resolves to the mocked values.
import { TestBed, inject, fakeAsync, tick } from '@angular/core/testing'; import { CatfactService } from './catfact.service'; import { HttpModule, Http, BaseRequestOptions, XHRBackend, ResponseOptions } from '@angular/http'; import { MockBackend } from '@angular/http/testing'; describe('CatfactService', () => { beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpModule], providers: [ CatfactService, MockBackend, BaseRequestOptions, { provide: Http, useFactory: (backend, options) => new Http(backend, options), deps: [MockBackend, BaseRequestOptions] } ], imports: [ HttpModule ] }); }); it('should return reasonable json', inject([CatfactService, MockBackend], fakeAsync((service: CatfactService, mockBackend) => { const mockResponse = { data: [{ id: 0, details: 'All cats are lions' }, { id: 1, details: 'Video 1' }, { id: 2, details: 'Video 2' }, { id: 3, details: 'Video 3' }, ] }; mockBackend.connections.subscribe(connection => { connection.mockRespond(new Response(JSON.stringify(mockResponse))); }); service.getFacts().subscribe((facts) => { facts.then((facts2) => { expect(facts2.length).toBe(4); expect(facts2[0].details).toEqual("All cats are lions"); }); }); tick(); }))); });
The fact that calling the subscribe method returns the actual response in the actual application, but a promise in the test, leads me to believe I've set up the mocking of the data incorrectly in the application.
I'm using the following versions of Angular:
ng -v _ _ ____ _ ___ / \\ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _| / △ \\ | '_ \\ / _` | | | | |/ _` | '__| | | | | | | / ___ \\| | | | (_| | |_| | | (_| | | | |___| |___ | | /_/ \\_\\_| |_|\\__, |\\__,_|_|\\__,_|_| \\____|_____|___| |___/ @angular/cli: 1.0.2 node: 7.9.0 os: darwin x64 @angular/common: 4.1.1 @angular/compiler: 4.1.1 @angular/core: 4.1.1 @angular/forms: 4.1.1 @angular/http: 4.1.1 @angular/platform-browser: 4.1.1 @angular/platform-browser-dynamic: 4.1.1 @angular/router: 4.1.1 @angular/cli: 1.0.2 @angular/compiler-cli: 4.1.1
The whole project is up on GitHub here: https://github.com/kenmazaika/AngularTesting
Here is a fixed version of the spec. The main issue was that you weren't importing the angular Response .
import { TestBed, inject, fakeAsync, tick } from '@angular/core/testing';
import { CatfactService } from './catfact.service';
import { HttpModule, Http, BaseRequestOptions, XHRBackend, ResponseOptions, Response, RequestOptions } from '@angular/http';
import { MockBackend } from '@angular/http/testing';
describe('CatfactService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [
CatfactService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, options) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
}
]
});
});
it('should return reasonable json', inject([CatfactService, MockBackend], fakeAsync((service: CatfactService, mockBackend) => {
const mockResponse = {
data: [
{ id: 0, details: 'All cats are lions' },
{ id: 1, details: 'Video 1' },
{ id: 2, details: 'Video 2' },
{ id: 3, details: 'Video 3' },
]
};
mockBackend.connections.subscribe(connection => {
connection.mockRespond(new Response(
new ResponseOptions({
body: [
{ id: 0, details: 'All cats are lions' },
{ id: 1, details: 'Video 1' },
{ id: 2, details: 'Video 2' },
{ id: 3, details: 'Video 3' },
]
})));
});
service.getFacts().subscribe((facts) => {
expect(facts.length).toBe(4);
expect(facts[0].details).toEqual("All cats are lions");
});
tick();
})));
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.