Javascript Angular2 http调用使测试执行两次
我有一个带有简单组件的Angular2应用程序Javascript Angular2 http调用使测试执行两次,javascript,unit-testing,typescript,angular,Javascript,Unit Testing,Typescript,Angular,我有一个带有简单组件的Angular2应用程序 @Component({ selector: 'Techs', template: '', providers: [HTTP_PROVIDERS] }) export class Techs { public techs: Tech[]; constructor(http: Http) { http .get('src/app/techs/techs.json') .map(response =
@Component({
selector: 'Techs',
template: '',
providers: [HTTP_PROVIDERS]
})
export class Techs {
public techs: Tech[];
constructor(http: Http) {
http
.get('src/app/techs/techs.json')
.map(response => response.json())
.subscribe(result => this.techs = result);
}
}
我的测试执行两次:
Chrome 49.0.2623(Mac OS X 10.11.4):执行6次成功中的0次(0秒/0秒)
日志:“测试结束”
Chrome 49.0.2623(Mac OS X 10.11.4):成功执行6次(0.182秒/0.153秒)
但是,如果删除Http调用,测试只执行一次
Chrome 49.0.2623(Mac OS X 10.11.4):成功执行6次(0.182秒/0.153秒)
这是我的测验
describe('techs component', () => {
it('should render 3 elements <tech>', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.createAsync(Techs)
.then(fixture => {
fixture.componentInstance.techs = [{}, {}, {}];
fixture.detectChanges();
const techs = fixture.nativeElement;
expect(techs.querySelectorAll('tech').length).toBe(3);
});
}));
});
description('techs component',()=>{
它('应该呈现3个元素',injectAsync([TestComponentBuilder],(tcb:TestComponentBuilder)=>{
返回tcb
.createAsync(Techs)
。然后(fixture=>{
fixture.componentInstance.techs=[{},{},{}];
fixture.detectChanges();
const techs=fixture.nativeElement;
expect(techs.queryselectoral('tech').length.).toBe(3);
});
}));
});
我认为您的问题来自HTTP调用的异步方面。我将看到两种解决方法:
- 另一种方法是模拟您的Http对象,以模拟Http调用。这可以使用
类来完成MockBackend
XHRBackend
类对其进行配置的步骤:
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
provide(XHRBackend, { useClass: MockBackend }),
];
});
以及在响应中返回所需内容的方法:
it('Should return a list of dogs', inject([XHRBackend, HttpService, Injector], (mockBackend, httpService, injector) => {
mockBackend.connections.subscribe(
(connection: MockConnection) => {
connection.mockRespond(new Response(
new ResponseOptions({
body: [ { name: 'test' }, ... ]
})));
}
(...)
- 也许您可以使用Angular2的伪异步支持。这样,您将能够以同步方式控制异步处理。。。看李>
fakeAsync
,我是否应该将其与第一种方法(模拟Http后端)结合使用?您可以同时使用这两种方法。FakeAsync允许您手动触发微任务。看这个问题:否则你怎么运行你的测试?我在使用因果报应。问题是,我不能使用fakeAsync
,因为TestComponentBuilder.createAsync
是异步的并返回一个承诺…顺便说一句,我注意到如果我在方法initData()
中移动http调用,然后从我的测试中,我重写这个方法,就像Techs.prototype.initData=function(){…}
中一样,然后它就可以工作了(可能是因为异步http调用不再进行了)