使用模拟后端测试HTTP

时间:2016-06-09 19:36:44

标签: angular karma-jasmine

我正在为Angular 2中的服务构建测试。构建模拟后端证明是一个真正的试验。我已经能够通过它成功地测试服务,但是我希望将这些服务与第三部分隔离开来。

我已经梳理了我能够找到的两篇主要文章(firstsecond以及angular docs

当我向实际的第三方服务成功发送http请求时,我不得不使用done();来确保测试等待请求完成。看来案件在这里是一样的。如果我不使用它,即使使用expect(1).toBe(2);,测试也会成功。当我使用它时,它会超时等待呼叫完成。错误:

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

这是我的代码:

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();
            });
        });
    });
});

如何使用mockbackend正确测试http调用?我怀疑上面引用的链接是否已过时,或者他们没有确认测试是否实际测试而不仅仅是在没有done();异步的情况下给出误报。

1 个答案:

答案 0 :(得分:2)

你非常接近。此处只有异步done不合适,因为inject必须替换此匿名回调。所以这是固定版本:

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

另一个问题是缺少beforeEach导入:

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

所以有一个Jasmine的beforeEach实例不允许使用inject