【发布时间】: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