Http 使用模拟后端测试Angular2服务
第一:我知道Angular2在alpha中,并且经常变化 我和安格拉尔一起工作。有一个具有http依赖关系的可注入服务,我想使用模拟后端进行测试。该服务在应用程序启动时工作,但我没有幸编写测试并让模拟后端响应。有什么见解吗?在测试设置或实现中有什么明显的地方我遗漏了吗 服务/核心技术:Http 使用模拟后端测试Angular2服务,http,dependency-injection,typescript,angular,Http,Dependency Injection,Typescript,Angular,第一:我知道Angular2在alpha中,并且经常变化 我和安格拉尔一起工作。有一个具有http依赖关系的可注入服务,我想使用模拟后端进行测试。该服务在应用程序启动时工作,但我没有幸编写测试并让模拟后端响应。有什么见解吗?在测试设置或实现中有什么明显的地方我遗漏了吗 服务/核心技术: import { Injectable } from 'angular2/angular2'; import { Http } from 'angular2/http'; @Injectable() expor
import { Injectable } from 'angular2/angular2';
import { Http } from 'angular2/http';
@Injectable()
export class CoreService {
constructor(public http:Http) {}
getStatus() {
return this.http.get('/api/status')
.toRx()
.map(res => res.json());
}
}
服务/核心规范:
import {
AsyncTestCompleter,
TestComponentBuilder,
By,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit
} from 'angular2/test';
import { MockBackend, MockConnection, BaseRequestOptions, Http, Response } from 'angular2/http';
import { Injector, bind } from 'angular2/angular2';
import { ObservableWrapper } from 'angular2/src/core/facade/async'
import { CoreService } from 'public/services/core'
export function main() {
describe('public/services/core', () => {
let backend: MockBackend;
let response: Response;
let coreService: CoreService;
let injector: Injector;
afterEach(() => backend.verifyNoPendingRequests());
it('should get status', inject([AsyncTestCompleter], (async) => {
injector = Injector.resolveAndCreate([
BaseRequestOptions,
MockBackend,
bind(Http).toFactory((backend, options) => {
return new Http(backend, options)
}, [MockBackend, BaseRequestOptions]),
bind(CoreService).toFactory((http) => {
return new CoreService(http);
}, [Http])
]);
backend = injector.get(MockBackend);
coreService = injector.get(CoreService);
response = new Response('foo');
ObservableWrapper.subscribe<MockConnection>(backend.connections, c => {
expect(c.request.url).toBe('/api/status');
c.mockRespond(response);
});
// attempt #1: fails because res argument is undefined
coreService.getStatus().subscribe(res => {
expect(res).toBe('');
async.done();
});
// attempt #2: fails because emitter.observer is not a function
ObservableWrapper.subscribe(coreService.getStatus(), res => {
expect(res).toBe('');
async.done();
});
}));
});
}
导入{
异步测试完成器,
TestComponentBuilder,
通过
之前,,
抄写员,
描述,
埃尔,
期待,,
iit,
注射
信息技术
退出
}来自“angular2/测试”;
从'angular2/Http'导入{MockBackend,MockConnection,BaseRequestOptions,Http,Response};
从'angular2/angular2'导入{Injector,bind};
从'angular2/src/core/facade/async'导入{ObservableWrapper}
从“public/services/core”导入{CoreService}
导出函数main(){
描述('公共/服务/核心',()=>{
让后端:MockBackend;
让反应:反应;
让coreService:coreService;
let注射器:注射器;
之后(()=>backend.verifyNoPendingRequests());
它('should get status',inject([AsyncTestCompleter],(async)=>{
injector=injector.resolveAndCreate([
BaseRequestOptions,
模拟后端,
绑定(Http).toFactory((后端,选项)=>{
返回新的Http(后端,选项)
},[MockBackend,BaseRequestOptions]),
绑定(CoreService).toFactory((http)=>{
返回新的CoreService(http);
},[Http])
]);
后端=injector.get(MockBackend);
coreService=注射器.get(coreService);
响应=新响应(“foo”);
ObservableWrapper.subscribe(backend.connections,c=>{
expect(c.request.url).toBe('/api/status');
c、 模拟应答(应答);
});
//尝试#1:失败,因为res参数未定义
coreService.getStatus().subscribe(res=>{
期望(res.)toBe(“”);
async.done();
});
//尝试#2:失败,因为emitter.observer不是函数
observewrapper.subscribe(coreService.getStatus(),res=>{
期望(res.)toBe(“”);
async.done();
});
}));
});
}
相关的:
我在寻找测试提示时发现了这个主题,但我看不到直接的答案,所以 这一个是基于角度RC.1 使用模拟后端测试服务 假设您的服务是:
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
@Injectable()
export class CoreService {
constructor(private http: Http) {}
getStatus() {
return this.http.get('/api/status');
}
}
对上述服务的测试如下所示:
import {
beforeEach,
beforeEachProviders,
describe,
expect,
inject,
it,
} from '@angular/core/testing';
import { provide } from '@angular/core';
import { BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
describe('Http', () => {
beforeEachProviders(() => [
CoreService,
BaseRequestOptions,
MockBackend,
provide(Http, {
useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
})
]);
beforeEach(inject([MockBackend], (backend: MockBackend) => {
const baseResponse = new Response(new ResponseOptions({ body: 'status' }));
backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
}));
it('should return response when subscribed to getStatus',
inject([CoreService], (coreService: CoreService) => {
coreService.getStatus().subscribe((res: Response) => {
expect(res.text()).toBe('status');
});
})
);
})
您真正需要看到的是在每个Providers之前在中进行适当的模拟。测试本身非常简单,最终订阅服务方法
注意:不要忘记先设置基本提供程序:
import { setBaseTestProviders } from '@angular/core/testing';
import {
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS,
TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
} from '@angular/platform-browser-dynamic/testing';
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
自从提出这个问题以来,我们确实升级到了Angular2 RC 1。我们的进口产品看起来像Wojciech Kwiatek(感谢您的回答!),但我们的测试策略略有不同。我们希望对请求和响应都进行断言。我们使用beforeachproviders()
,而不是使用beforeach()
,在这里我们创建自己的注入器并保存对测试和模拟后端下的服务的引用。这允许我们对请求进行断言并在测试中管理响应,并且允许我们在每次测试后使用verifyNoPendingRequests()
方法
describe('core-service', () => {
let service: CoreService;
let backend: MockBackend;
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate(<any> [
CoreService,
BaseRequestOptions,
MockBackend,
provide(Http, {
useFactory: (mockBackend, defaultOptions) => new Http(mockBackend, defaultOptions),
deps: [MockBackend, BaseRequestOptions]
})
]);
service = <CoreService> injector.get(CoreService);
backend = <MockBackend> injector.get(MockBackend);
});
afterEach(() => backend.verifyNoPendingRequests());
it('should get status', () => {
backend.connections.subscribe((c: MockConnection) => {
expect(c.request.url).toEqual('api/status');
c.mockRespond(new Response(new ResponseOptions({ body: 'all is well' })));
});
service.getStatus().subscribe((status) => {
expect(status).toEqual('all is well');
});
}));
});
description('core-service',()=>{
让服务:核心服务;
让后端:MockBackend;
在每个之前(()=>{
injector=ReflectiveInjector.resolveAndCreate(您有任何错误吗?它实际上在做什么?我将错误包含在内联中。直接订阅(coreService.getStatus().subscribe(…)会收到一个错误,res参数返回为未定义。如果我使用ObservaleWrapper.subscribe(…),它抛出一个错误,说emitter.observable不是一个函数。谢谢你的提问。如果你将从'angular2/test'
更改为从'angular2/test\u lib'
,会发生什么?它是否工作?当你测试请求url时,你不会检查它是否是GET、POST、DELETE等。只是url字符串。这与我现在所做的相同。我不知道如何测试请求的类型。在Angular 1中,我们有$httpBackend.expectGET('api/status')之类的东西你知道我们如何测试它吗?谢谢,第一行不应该是从“angular2/core”读,而不是从“angular2/angular2”读,
?当我尝试做后者时,我的编译器抱怨道。感谢这一点和更新的Plunker。对我来说,最后一个难题是阅读要创建的ResponseOptions对象一个很好的模拟回答。一旦我解决了这个问题,我的测试就使用了你的策略。