问题描述
我是Angular2,Karma和Jasmine的新手.目前我正在使用Angular 2 RC4 Jasmine 2.4.x我有一个Angular 2服务,它会定期像这样调用http服务:
Hi I'm relatively new to Angular2, Karma and Jasmine. Currently I'm using Angular 2 RC4 Jasmine 2.4.xI have an Angular 2 service which periodically calls an http service like this:
getDataFromDb() { return Observable.timer(0, 2000).flatMap(() => {
return this.http.get(this.backendUrl)
.map(this.extractData)
.catch(this.handleError);
});
}
现在,我要测试功能.出于测试目的,我通过执行以下操作在没有Observable.timer的单独函数上测试了"http.get":
Now I want to test the functionality. For testing purposes I have just tested the "http.get" on a separate function without the Observable.timer by doing:
const mockHttpProvider = {
deps: [MockBackend, BaseRequestOptions],
useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
}
}
describe('data.service test suite', () => {
var dataFromDbExpected: any;
beforeEachProviders(() => {
return [
DataService,
MockBackend,
BaseRequestOptions,
provide(Http, mockHttpProvider),
];
});
it('http call to obtain data',
inject(
[DataService, MockBackend],
fakeAsync((service: DataService, backend: MockBackend) => {
backend.connections.subscribe((connection: MockConnection) => {
dataFromDbExpected = 'myData';
let mockResponseBody: any = 'myData';
let response = new ResponseOptions({ body: mockResponseBody });
connection.mockRespond(new Response(response));
});
const parsedData$ = service.getDataFromDb()
.subscribe(response => {
console.log(response);
expect(response).toEqual(dataFromDbExpected);
});
})));
});
我显然想使用Observable.timer测试整个功能.我认为可能要使用rxjs框架中的TestScheduler,但是我怎样才能告诉我只将Timer函数重复x次呢?我在打字稿上下文中找不到任何使用它的文档.
I obviously want to test the whole function with the Observable.timer. I think one might want to use the TestScheduler from the rxjs framework, but how can I tell to only repeat the timer function for x times? I couln't find any documentation using it in the typescript context.
我正在使用rxjs 5 beta 6
I'm using rxjs 5 beta 6
添加了Angular 2.0.0最终版本的工作示例:
Added working example for Angular 2.0.0 final release:
describe('when getData', () => {
let backend: MockBackend;
let service: MyService;
let fakeData: MyData[];
let response: Response;
let scheduler: TestScheduler;
beforeEach(inject([Http, XHRBackend], (http: Http, be: MockBackend) => {
backend = be;
service = new MyService(http);
fakeData = [{myfake: 'data'}];
let options = new ResponseOptions({ status: 200, body: fakeData });
response = new Response(options);
scheduler = new TestScheduler((a, b) => expect(a).toEqual(b));
const originalTimer = Observable.timer;
spyOn(Observable, 'timer').and.callFake(function (initialDelay, dueTime) {
return originalTimer.call(this, initialDelay, dueTime, scheduler);
});
}));
it('Should do myTest', async(inject([], () => {
backend.connections.subscribe((c: MockConnection) => c.mockRespond(response));
scheduler.schedule(() => {
service.getMyData().subscribe(
myData => {
expect(myData.length).toBe(3,
'should have expected ...');
});
}, 2000, null);
scheduler.flush();
})));
});
推荐答案
您需要将TestScheduler注入到beforeEach部分内部的timer方法中:
You need to inject the TestScheduler into the timer method inside a beforeEach part:
beforeEach(function() {
this.scheduler = new TestScheduler();
this.scheduler.maxFrames = 5000; // Define the max timespan of the scheduler
const originalTimer = Observable.timer;
spyOn(Observable, 'timer').and.callFake(function(initialDelay, dueTime) {
return originalTimer.call(this, initialDelay, dueTime, this.scheduler);
});
});
之后,您完全可以使用scheduleAbsolute
来控制时间:
After that you have full control of the time with scheduleAbsolute
:
this.scheduler.schedule(() => {
// should have been called once
// You can put your test code here
}, 1999, null);
this.scheduler.schedule(() => {
// should have been called twice
// You can put your test code here
}, 2000, null);
this.scheduler.schedule(() => {
// should have been called three times
// You can put your test code here
}, 4000, null);
this.scheduler.flush();
您需要scheduler.flush()
来启动TestScheduler.
You need scheduler.flush()
to start the TestScheduler.
因此,如果您只想测试X次,则可以根据需要频繁使用计划功能(以及正确的绝对时间(以毫秒为单位)).
edit: so if you want to only test it X times, use the schedule functions as often (and with the right absolute times in milliseconds) as you wish.
edit2:我添加了缺少的调度程序开始
edit2: I added the missing scheduler start
edit3:我更改了它,因此应该与RxJs5一起使用
edit3: I changed it so should be working with RxJs5
edit4:添加maxFrames
设置,因为默认设置为750ms,这将阻止测试运行时间更长的序列.
edit4: Add maxFrames
setting since the default is 750ms and will prevent testing longer-running sequences.
这篇关于使用打字稿,业力和茉莉花进行单元测试RxJS Observable.timer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!