我在测试我的 Angular 应用程序时试图模拟一些 http 请求。我正在通过使用 Angular 的 MockBackEnd 和 MockConnection 来关注互联网上使用 fakeBackendProvider 的流行示例。尽管我很好地理解了代码,但我想更详细地了解这些提供程序的内部工作。
他们如何拦截http请求?例如,当我的代码调用 http.get() 时,谁迷上了什么,谁替换了什么,以及如何?
任何参考资料都会非常有帮助。
我在测试我的 Angular 应用程序时试图模拟一些 http 请求。我正在通过使用 Angular 的 MockBackEnd 和 MockConnection 来关注互联网上使用 fakeBackendProvider 的流行示例。尽管我很好地理解了代码,但我想更详细地了解这些提供程序的内部工作。
他们如何拦截http请求?例如,当我的代码调用 http.get() 时,谁迷上了什么,谁替换了什么,以及如何?
任何参考资料都会非常有帮助。
尝试 HttpClient,它是 Angular 4.3.X 的新功能。它提供了实现 HttpInterceptor 的简单方法。拦截,
使用具有方法 Intercept 的 HttpInterceptor 接口,您必须在类中重写该方法。下面给出的示例代码,
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/Observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/Observable/of';
import 'rxjs/add/operator/do';
export class YourInterceptor implements HttpInterceptor{
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
// Your interceptor code comes here.
// you wish to change the request, change here.
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.auth.getToken()}`
}
});
return next.handle(request);
}
}
我认为您也正在尝试为此编写单元测试,以便这样做
Angular 4 提供了两个很棒的类来使用 HttpTestingController,HttpClientTestingModule。确保在使用之前在 module.ts 文件中提供 HttpClientModule。
import { TestBed, inject, getTestBed } from '@angular/core/testing';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { HttpTestingController, HttpClientTestingModule } from '@angular/common/http/testing';
import { YourService } from './get-name-service.service';
describe('YourService', () => {
let injector: TestBed;
let httpMock: HttpTestingController;
let yourService: YourService;
beforeEach(() => {
TestBed.configureTestingModule({
imports:[HttpClientTestingModule],
providers: [YourService]
});
injector = getTestBed();
httpMock = injector.get(HttpTestingController);
yourService = TestBed.get(YourService);
});
describe('#getUsers', () => {
it('should return an Observable<User[]>', () => {
const dummyUsers = [
{ login: 'John' },
{ login: 'Doe' }
];
yourService.getNames().subscribe(users => {
console.log('I am here in yourService method');
expect(users.length).toBe(2);
expect(users).toEqual(dummyUsers);
});
const req = httpMock.expectOne('http://localhost:8080/dev/getNames');
expect(req.request.method).toBe("GET");
req.flush(dummyUsers);
});
});
});
对于 mockbackend,你可以做这样的事情,
在您的应用程序中包含正确的提供程序,如下所示,在您的情况下它将是 Http。...提供者:[Http,...]
您的测试文件将包含以下代码或配置,如果您注意到我们使用了 ReflectiveInjector 类和方法 resolveAndCreate。此方法将帮助您创建所需类及其所有依赖项的对象。例如 this.yourService = this.injector.get(YourService);
以下两行将帮助您的测试代码与假后端连接
{provide: ConnectionBackend, useClass: MockBackend},
{provide: RequestOptions, useClass: BaseRequestOptions},
提供和使用类,现在无论何时创建 ConnectionBackend 类对象,它都会与 MockBackend 类对象映射,
现在每个示例的测试用例它('getNames()应该返回一些名称',可以使用 this.lastConnection 将用于连接您的模拟后端,您必须使用 Response 和 ResponseOptions 类创建一个响应在下面的代码片段中给出。
describe('MockBackend NameService Example', () => {
beforeEach(() => {
this.injector = ReflectiveInjector.resolveAndCreate([
{provide: ConnectionBackend, useClass: MockBackend},
{provide: RequestOptions, useClass: BaseRequestOptions},
Http,
YourService,
]);
this.yourService = this.injector.get(YourService);
this.backend = this.injector.get(ConnectionBackend) as MockBackend;
this.backend.connections.subscribe((connection: any) => this.lastConnection = connection);
});
it('getNames() should return some names', fakeAsync(() => {
let result: String[];
this.yourService.getNames().then((names: String[]) => result = names);
this.lastConnection.mockRespond(new Response(new ResponseOptions({
body: JSON.stringify({data: ["Deepak Test1", "Deepak Test2"]}),
})));
tick();
expect(result.length).toEqual(2, 'should contain given amount of Names');
expect(result[0]).toEqual("Deepak Test1", ' NAME_ONE should be the first Name');
expect(result[1]).toEqual("Deepak Test2", ' NAME_TWO should be the second Name');
}));
});