简体   繁体   中英

Angular 2 Observable Service Integration Test

I would like to create an integration test and hit my actual service (not a mock). How would I do that in Angular 2?

Here is what I have for my observable service:

import { Injectable } from '@angular/core';
import { Http, Response, RequestOptions, Headers } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';

import { UserDetail } from '../models/user-detail.model';

export class GetUserDetailService {
  private _userDetailUrl : string = 'http://ourserver/api/GetCurrentUserDetail';

  constructor(private _http: Http) { }

  getUserDetail(): Observable<UserDetail> {
        return this._http.get(this._userDetailUrl)
        .map((response: Response) => <UserDetail> response.json())
        .do(data => console.log('All: ' +  JSON.stringify(data)))
        .catch(this.handleError);
  }

  private handleError(error: Response) {
      console.error(error);
      return Observable.throw(error.json().error || 'Server error');
  }
}

How to I ensure that an object is returned from the service?

// Third party imports
import { Observable } from 'rxjs/Observable';
import { HttpModule } from '@angular/http';

// Our imports
import { GetUserDetailService } from './get-user-detail.service';
import { UserDetail } from '../models/user-detail.model';

describe('GetUserDetailService', () => {

  beforeEach(() => {
    // What do I put here?
  });

  it('should get the user detail', () => {
    // What do I put here?
  });
});

As shown in this example , a way to do XHR integration tests in Angular is to just use HttpModule without MockBackend :

describe('GetUserDetailService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      provide: [GetUserDetailService],
      imports: [HttpModule]
    });
  });

  it('should get user detail', async(inject([Http, GetUserDetailService], (http, svc) => {
    spyOn(http, 'get').and.callThrough();

    svc.getUserDetail().subscribe(
      (userDetail: UserDetail) => {
        expect(userDetail).toEqual(...);
      }
    );

    expect(http.get).toHaveBeenCalledWith(...);
  })));

  it('shouldnot get user detail', async(inject([Http, GetUserDetailService], (http, svc) => {
    spyOn(http, 'get').and.callThrough();
    spyOn(svc, 'handleError').and.callThrough();
    svc._userDetailUrl = 'wrong url';

    svc.getUserDetail().subscribe(
      (userDetail: UserDetail) => { throw new Error('should fail') },
      (error) => {
        expect(svc.handleError).toHaveBeenCalledWith(...);
        expect(error).toEqual(...);
      }
    );

    expect(http.get).toHaveBeenCalledWith('wrong url');
  })));
});

fakeAsync helper can't be used in really asynchronous test (there should be be an error if is used), so it is async .

The first test fails automatically if there was an error in observable, so it doesn't have to be caught in subscribe .

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