【问题标题】:How to test Angular httpClient methods inside a promise in jasmine?如何在茉莉花的承诺中测试 Angular httpClient 方法?
【发布时间】:2018-01-31 13:23:22
【问题描述】:

我知道如何使用模拟后端以及 Promise 来测试 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);
      });
    };
  }

抛出这个错误:Uncaught TypeError:

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

【问题讨论】:

  • 您的规格代码在哪里?到目前为止,您尝试过什么?
  • 抛出这个错误:Uncaught TypeError: _this._http.get$ is not a function at localhost:9876/_karma_webpack_/polyfills.bundle.js:2281 it('returns null if the http call can't 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(); }); });
  • 请将该信息添加到问题中。
  • 有关在服务文件中导入和构建的更多信息

标签: javascript angular typescript jasmine httpclient


【解决方案1】:

使用 HttpClientTestingModule 模拟 http 请求

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

在应用开发中,我调用了返回查询的service方法,然后我subscribe(),我已经在当前组件中考虑了成功和错误的查询,显示一些通知给用户 然后你可以从一个函数到一个单独的函数进行查询,然后做这样的事情:

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

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 2017-06-02
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    相关资源
    最近更新 更多