Testing HTTP with mockbackends

不羁的心 提交于 2019-12-24 15:30:41

问题


I'm working on building out tests for my services in Angular 2. Building out the mock backends is proving to be a real trial. I have been able to test the services with it making actual HTTP requests successfully but I would like to keep these segregated from the third part.

I've combed through the two main articles I have been able to find (first, second as well as the angular docs.

When I was making successful http requests to actual third party services, I had to use done(); to ensure that the test waited for the request to complete. It seems that the case is the same here. If I do not use it, the test will be a success even with expect(1).toBe(2);. When I do use it, it times out waiting for the call to complete. Error:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

Here's my code:

import {
    it,
    inject,
    describe,
    beforeEachProviders,
    expect,
} from '@angular/core/testing';
import { BaseRequestOptions, Response, ResponseOptions, Http } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';

import { AccountService } from './../../source/scripts/services/account.service';
import { provide } from '@angular/core';

describe('AccountService', () => {
    // let service;

    beforeEachProviders(() => [
        AccountService,
        BaseRequestOptions,
        MockBackend,
        provide(Http, {
            deps: [MockBackend, BaseRequestOptions],
            useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
                return new Http(backend, defaultOptions);
            },
        }),
    ]);

    beforeEach(<any>inject([MockBackend], (backend: MockBackend) => {
        const baseResponse = new Response(new ResponseOptions({ body: 'got response' }));
        backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
    }));

    // We use 'done' for async callbacks (http calls)    
    it('should return mocked response', (done) => {

        inject([AccountService], (testService: AccountService) => {
            testService.getUsers().subscribe((res: Response) => {
                expect(res.text()).toBe('got response');
                expect(1).toBe(2);
                done();
            });
        });
    });
});

How do I properly test http calls with a mockbackend? I suspect that either the links I referenced above are out of date or they didn't confirm that the test was actually testing rather than just giving false positives without the async of done();.


回答1:


You were very close. Only the async done is not appropriate here because inject has to replace this anonymous callback. So here is the fixed version:

it('should return mocked response', inject([AccountService], (testService: AccountService) => {
  testService.getUsers().subscribe((res: Response) => {
    expect(res.text()).toBe('got response');
    expect(1).toBe(2);
  });
}));

Another problem is missing beforeEach import:

import {
    it,
    inject,
    describe,
    beforeEach, // <-- this one was missing
    beforeEachProviders,
    expect,
} from '@angular/core/testing';

So there was a Jasmine's beforeEach instance which doesn't allow to use inject.



来源:https://stackoverflow.com/questions/37734760/testing-http-with-mockbackends

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!