如何在 jasmine 中的承诺中测试 Angular httpClient 方法



我知道如何使用模拟后端以及承诺来测试http。虽然我正在努力寻找一种解决方案来测试承诺中的http方法。任何建议将不胜感激。下面是包含 promise 中带有 http 方法的函数的函数:

import { Injectable } from '@angular/core';
import { AbstractControl, FormGroup, FormControl, ValidatorFn, AsyncValidatorFn } from '@angular/forms';
import { Headers, RequestOptions } from '@angular/http';
import { Store } from '@ngrx/store';
import { HttpService, IHttpResponse } from '@mystique/mystique-utils/http';
import { IRootState } from '@mystique/mystique-state/root';
@Injectable()
export class ValidatorsService {
  regex: { email: string; password: string } = { email: null, password: null };
  constructor(private _http: HttpService, private _store: Store<IRootState>) {
    this._store.select('config', 'regex').subscribe(regex => (this.regex = regex));
  }
recordExistsOnServer(model: string, lookupField: string, savedValue: string, authToken: string): AsyncValidatorFn {
    model += 's';
    let validationDebounce;
    return (control: AbstractControl) => {
      const queryParams = [{ key: lookupField, value: control.value }];
      clearTimeout(validationDebounce);
      return new Promise((resolve, reject) => {
        validationDebounce = setTimeout(() => {
          if (control.value === '' || control.value === savedValue) {
            return resolve(null);
          }
          this._http.get$(`/${model}`, authToken, queryParams).subscribe((httpResponse: IHttpResponse) => {
            if (!httpResponse.data) {
              savedValue = control.value;
            }
            return !httpResponse.data ? resolve(null) : resolve({ recordExistsOnServer: true });
          });
        }, 400);
      });
    };
  }

引发此错误:未捕获的类型错误:

_this._http.get$ is not a function at localhost:9876/_karma_webpack_/polyfills.bundle.js:2281 

这是我的测试用例,最后一个 it(( 失败了:

import { TestBed, inject } from '@angular/core/testing';
import { FormGroup, FormControl } from '@angular/forms';
import { StoreModule, Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { HttpService } from '@mystique/mystique-utils/http';
import { HttpServiceStub } from '@mystique/mystique-stubs';
import { ValidatorsService } from './validators.service';
import { rootReducer } from '@mystique/mystique-state/root';
describe('ValidatorsService', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [
                StoreModule.forRoot({
                    config: rootReducer.config
                })
            ],
            providers: [{ provide: HttpService, useClass: HttpServiceStub }, ValidatorsService]
        });
    });
    let service, http, store;
    beforeEach(() => {
        http = TestBed.get(HttpService);
        store = TestBed.get(Store);
        service = TestBed.get(ValidatorsService);
    });
    describe('when checking if a record exists on the server', () => {
        let control, result, getSpy;
        beforeEach(() => {
            getSpy = spyOn(http, 'getAll$');
        });
        it('returns null if the user types the same value', done => {
            control = new FormControl('bob');
            result = service.recordExistsOnServer('user', 'username', 'bob', 'token');
            result(control)['then'](r => {
                expect(r).toEqual(null);
                done();
            });
        });
        it('returns null if the user types an empty string', done => {
            control = new FormControl('');
            result = service.recordExistsOnServer('user', 'username', 'bob');
            result(control)['then'](r => {
                console.log('r: ' + r)
                expect(r).toEqual(null);
                done();
            });
        });
        it('returns null if the http call cannot find a record', done => {
            getSpy.and.returnValue(Observable.of({ data: null }));
            control = new FormControl('bobby');
            result = service.recordExistsOnServer('user', 'username', 'bob');
            result(control)['then'](r => {
                expect(r).toEqual(null);
                done();
            });
        });
    });
});

这是我的http.service.ts:

import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { IRootState } from '@mystique/mystique-state/root';
import { HttpClient, HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/retry';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { IBaseModel } from '@spawntech/xmen-core-domain-models';
export interface IHttpQuery {
  key: string;
  value: string | number;
}
export interface IHttpResponse {
  success: boolean;
  status: number;
  statusText: string;
  message: string;
  data?: any | any[];
  error?: string;
  token?: string;
}
@Injectable()
export class HttpService {
  apiBaseUrl: string = null;
  httpRetries = 3;
  constructor(private _http: HttpClient, private _store: Store<IRootState>) {
    this._store.select('config', 'apiBaseUrl').subscribe(url => (url ? (this.apiBaseUrl = url) : this.apiBaseUrl));
  }
  get$(restUrl: string, authToken: string, queryParams?: IHttpQuery[]): Observable<IHttpResponse> {
    if (!restUrl) {
      throw new Error('A restful url extension must be supplied');
    }
    const headers = this._prepareAuthHeader(authToken);
    const params = this._prepareQueryParams(queryParams);
    console.log('in http service---------------')
    return this._http
      .get<IHttpResponse>(this.apiBaseUrl + restUrl, { headers, params })
      .retry(this.httpRetries)
      .catch((response: HttpErrorResponse) => this._handleError(response));
  }
}

使用 HttpClientTestingModule 进行模拟 http 请求

TestBed.configureTestingModule({
      imports: [..., HttpClientTestingModule],
      providers: [...]
    })

在应用程序的开发中,我调用返回查询的服务方法,然后我订阅((,并且我已经考虑了当前组件中的成功和错误查询,向用户显示一些通知然后,您可以将查询从一个函数带到一个单独的函数,并执行以下操作:

spyOn (service, 'confirmEmail').
       .returnValue (Observable.of (new HttpResponse ({body: '', status: 204}))));

最新更新