Angular 2 RC6测试HTTP.get抛出错误,get()方法不存在

时间:2016-10-25 00:07:04

标签: http angular karma-jasmine

我正在尝试为包含http.get方法的方法编写单元测试,并且我遇到了使其工作的问题。我知道将用于Http的类设置为MockBackend是错误的,这也是我收到错误的原因:get() method does not exist但是我不知道我应该在http后面使用什么样的模拟类。

describe('Http Service', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        SharedHttpService,
        {
          provide: SharedCookieService,
          useClass: MockSharedCookieService
        }, {
          provide: Http,
          useClass: MockBackend
        }
      ]
    });
  });

  beforeEach(inject([ SharedHttpService, Http ], ( _httpService: SharedHttpService, _mockBackend: MockBackend ) => {
    httpService = _httpService;
    mockBackend = _mockBackend;
  }));

  describe('get', () => {
    it(`should call setAuthToken and make the get request with the authorization headers`, () => {
      let fakeUrl: string = 'www.fakeurl.com';
      httpService.headers = mockHeaders;
      spyOn(httpService, 'setAuthToken');
      spyOn(httpService.http, 'get').and.callThrough();
      mockBackend.connections.subscribe((connection: MockConnection) => {
        let options: ResponseOptions = new ResponseOptions({
          body: { }
        });
        connection.mockRespond(new Response(options));
      });
      httpService.get(fakeUrl, () => { })
      .subscribe(() => {
        expect(httpService.setAuthToken).toHaveBeenCalled();
        expect(httpService.http.get).toHaveBeenCalledWith(fakeUrl, { headers: mockHeaders });
      });
    });
  });

代码背后:

export class SharedHttpService {
  private headers: Headers = new Headers();

  constructor(  private cookieService: SharedCookieService,
                private http: Http  ) { }

  public get(address: string, callback: any): Observable<any> {
    return this.setAuthToken()
      .map(() => { })
      .switchMap(() => {
        return this.http.get(address, { headers: this.headers })
          .map(callback)
          .catch(( error: any ) => this.handleError(error));
      });
  }
}

1 个答案:

答案 0 :(得分:2)

您需要使用MockBackend而非作为 Http,但要创建 Http。你用工厂做到了

imports: [ HttpModule // this is needed ],
providers: [
  SharedHttpService,
  MockBackend,
  BaseRequestOptions    // @angular/http
  {
    provide: Http,
    deps: [ MockBackend, BaseRequestOptions ],
    useFactory: (backend: MockBackend, options: BaseRequestOptions) => {
      return new Http(backend, options);
    }
  }
]

现在您可以将MockBackend注入测试中,以便模拟连接上的响应。

                                  // MockBackend not Http
beforeEach(inject([ SharedHttpService, MockBackend ],
          ( _httpService: SharedHttpService, _mockBackend: MockBackend ) => {
  httpService = _httpService;
  mockBackend = _mockBackend;
}));

另一方面,您需要使用异步测试,因为对subscribe的调用异步解析

import { async } from '@angular/core/testing';

it('...', async(() => {

}));

另见Angular 2 Testing - Async function call - when to use