简体   繁体   中英

Angular 4: Using mockRespond with RxJS Observables

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM