Angular:使用 MockBackend 测试 HTTP,真的需要 async() 吗?
Angular: Testing HTTP with MockBackend, is async() really required?
我正在使用 MockBackend
来测试依赖于 @angular/http
的代码。
网络上的所有示例都使用异步测试设置,如下所示:
thoughtram: Testing Services with Http in Angular
describe('getVideos()', () => {
it('should return an Observable<Array<Video>>',
async(inject([VideoService, MockBackend], (videoService, mockBackend) => {
videoService.getVideos().subscribe((videos) => {
expect(videos.length).toBe(4);
expect(videos[0].name).toEqual('Video 0');
expect(videos[1].name).toEqual('Video 1');
expect(videos[2].name).toEqual('Video 2');
expect(videos[3].name).toEqual('Video 3');
expect("THIS TEST IS FALSE POSITIVE").toEqual(false);
});
const mockResponse = {
data: [
{ id: 0, name: 'Video 0' },
{ id: 1, name: 'Video 1' },
{ id: 2, name: 'Video 2' },
{ id: 3, name: 'Video 3' }
]
};
mockBackend.connections.subscribe((connection) => {
connection.mockRespond(new Response(new ResponseOptions({
body: JSON.stringify(mockResponse)
})));
});
})));
});
不过,我试过了,我很确定 MockBackend 完全同步执行:
describe('getVideos()', () => {
it('should return an Observable<Array<Video>>',
inject([VideoService, MockBackend], (videoService, mockBackend) => {
const mockResponse = {
data: [
{ id: 0, name: 'Video 0' },
{ id: 1, name: 'Video 1' },
{ id: 2, name: 'Video 2' },
{ id: 3, name: 'Video 3' },
]
};
mockBackend.connections.subscribe((connection) => {
connection.mockRespond(new Response(new ResponseOptions({
body: JSON.stringify(mockResponse)
})));
});
let videos;
videoService.getVideos().subscribe(v => videos = v);
// synchronous code!?
expect(videos.length).toBe(4);
expect(videos[0].name).toEqual('Video 0');
expect(videos[1].name).toEqual('Video 1');
expect(videos[2].name).toEqual('Video 2');
expect(videos[3].name).toEqual('Video 3');
}));
});
我在这里创建了一个关于 plunker 的完整示例:
https://plnkr.co/edit/I3N9zL?p=preview
自从撰写这些文章后,一定有一些更改。
有人可以指出那个重大变化吗?还是我错过了一个重要的事实?
您的假设完全正确,MockConnection.mockRespond()
发出同步信号。 async()
在此特定测试中不需要。
我是你在问题中提到的那篇文章的作者,我已经相应地更新了它。
非常感谢您指出这一点!
我正在使用 MockBackend
来测试依赖于 @angular/http
的代码。
网络上的所有示例都使用异步测试设置,如下所示:
thoughtram: Testing Services with Http in Angular
describe('getVideos()', () => {
it('should return an Observable<Array<Video>>',
async(inject([VideoService, MockBackend], (videoService, mockBackend) => {
videoService.getVideos().subscribe((videos) => {
expect(videos.length).toBe(4);
expect(videos[0].name).toEqual('Video 0');
expect(videos[1].name).toEqual('Video 1');
expect(videos[2].name).toEqual('Video 2');
expect(videos[3].name).toEqual('Video 3');
expect("THIS TEST IS FALSE POSITIVE").toEqual(false);
});
const mockResponse = {
data: [
{ id: 0, name: 'Video 0' },
{ id: 1, name: 'Video 1' },
{ id: 2, name: 'Video 2' },
{ id: 3, name: 'Video 3' }
]
};
mockBackend.connections.subscribe((connection) => {
connection.mockRespond(new Response(new ResponseOptions({
body: JSON.stringify(mockResponse)
})));
});
})));
});
不过,我试过了,我很确定 MockBackend 完全同步执行:
describe('getVideos()', () => {
it('should return an Observable<Array<Video>>',
inject([VideoService, MockBackend], (videoService, mockBackend) => {
const mockResponse = {
data: [
{ id: 0, name: 'Video 0' },
{ id: 1, name: 'Video 1' },
{ id: 2, name: 'Video 2' },
{ id: 3, name: 'Video 3' },
]
};
mockBackend.connections.subscribe((connection) => {
connection.mockRespond(new Response(new ResponseOptions({
body: JSON.stringify(mockResponse)
})));
});
let videos;
videoService.getVideos().subscribe(v => videos = v);
// synchronous code!?
expect(videos.length).toBe(4);
expect(videos[0].name).toEqual('Video 0');
expect(videos[1].name).toEqual('Video 1');
expect(videos[2].name).toEqual('Video 2');
expect(videos[3].name).toEqual('Video 3');
}));
});
我在这里创建了一个关于 plunker 的完整示例: https://plnkr.co/edit/I3N9zL?p=preview
自从撰写这些文章后,一定有一些更改。 有人可以指出那个重大变化吗?还是我错过了一个重要的事实?
您的假设完全正确,MockConnection.mockRespond()
发出同步信号。 async()
在此特定测试中不需要。
我是你在问题中提到的那篇文章的作者,我已经相应地更新了它。
非常感谢您指出这一点!