我知道如何使用模拟后端和promises来测试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);
});
};
}
引发此错误:未捕获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));
}
}
答案 0 :(得分:0)
使用HttpClientTestingModule进行模拟http请求
TestBed.configureTestingModule({
imports: [..., HttpClientTestingModule],
providers: [...]
})
在开发应用程序时,我调用返回查询的service方法,然后我订阅()并且我已经考虑了当前组件中的成功和错误查询,向用户显示了一些通知 然后你可以从一个函数查询一个单独的函数,并做这样的事情:
spyOn (service, 'confirmEmail').
.returnValue (Observable.of (new HttpResponse ({body: '', status: 204}))));