【问题标题】:Angular 2 Observable Service Integration TestAngular 2 Observable 服务集成测试
【发布时间】:2017-09-25 14:52:24
【问题描述】:

我想创建一个集成测试并点击我的实际服务(不是模拟)。我将如何在 Angular 2 中做到这一点?

以下是我的可观察服务:

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

如何确保从服务返回对象?

// 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?
  });
});

【问题讨论】:

  • 您要检查服务返回的值还是绑定到组件变量的值?
  • 最好做类似 let response = callTheService;然后做一些类似expect(response).toBeDefined();还有expect(response.UserId).toBeDefined();
  • 你想用 Http 服务的 mock 来测试实际的服务吗?还是您想在完全没有模拟的情况下测试服务(这意味着您的 api 在您运行测试时必须可用)?您可以仅模拟 Http 服务,以提供看起来像您的 API 答案的虚假答案,并在您从 API 获得这个或那个响应时观察您的服务的反应。
  • 我正在测试实际的 Http 服务,而不是模拟(集成测试)。

标签: javascript angular jasmine rxjs


【解决方案1】:

this example 所示,在 Angular 中进行 XHR 集成测试的一种方法是只使用 HttpModule 而不使用 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 不能用于真正的异步测试(使用应该会有错误),所以是async

如果 observable 中有错误,第一个测试会自动失败,因此不必在 subscribe 中捕获。

【讨论】:

  • 我无法编译它。今天晚些时候我会告诉你这个错误。
猜你喜欢
  • 2017-08-17
  • 2017-07-01
  • 2021-04-28
  • 1970-01-01
  • 2017-06-03
  • 2021-06-26
  • 1970-01-01
  • 2017-12-20
  • 1970-01-01
相关资源
最近更新 更多