我已从RC4迁移到最终版本(2.1.0),我正在重构我的单元测试以符合2.1.0语法。除了HTTP模拟之外,这很容易。
我找不到任何关于如何在2.1.0
中模拟HTTP请求的示例这是一个RC4 HTTP单元测试。我将如何在最终版本2.1.0中重写它?
it('ngOnInit()',
async(inject([TestComponentBuilder, XHRBackend], (tcb:TestComponentBuilder, mockBackend:MockBackend) => {
tcb.createAsync(Route1ListComponent).then((fix:ComponentFixture<Route1ListComponent>) => {
// THIS BLOCK OF CODE I NEED HELP TO RE-WRITE TO 2.1.0
mockBackend.connections.subscribe(
(connection:MockConnection) => {
connection.mockRespond(new Response(
new ResponseOptions({
body: persons
}
)));
});
// THIS BLOCK OF CODE WILL NOT CHANGE
let instance = fix.componentInstance;
instance.ngOnInit();
expect(instance.persons.length).toBe(3);
});
})));
注意:请不要提供RC代码。感谢
答案 0 :(得分:4)
您需要做的第一件事是配置TestBed
。不再有TestComponentBuilder
。使用TestBed
,就像从头开始配置@NgModule
,仅适用于测试环境。这意味着您将测试中的组件添加到declarations
,将所有提供商添加到provider
,并将任何导入添加到imports
。
要为Http
提供商配置模拟后端,您只需从Http
创建MockBackend
。
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ HttpModule ],
declarations: [ RouteListComponent ],
providers: [
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend: MockBackend, options: BaseRequestOptions) => {
return new Http(backend, options);
},
deps: [ MockBackend, BaseRequestOptions ]
}
]
})
})
这应该是配置,假设您不需要任何其他我不知道的提供商或进口。
对于测试,您首先要进行async
测试,因为您将在测试中进行异步操作。这与RC没有变化,您只需使用async
。如果组件使用templateUrl
(并且您没有使用Webpack),则需要调用TestBed.compileComponents()
,否则无需调用TestBed.createComponent
。之后,您可以使用let fixture: ComponentFixture<RouteListComponent>;
let component: RouteListComponent;
beforeEach(async(() => {
TestBed.configureTestingModule({ ... })
.compileComponents().then(() => {
fixture = TestBed.createComponent(RouteListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
}));
it('...', async(inject([MockBackend], (backend: MockBackend) => {
})))
@angular/core/testing
以上与测试相关的所有内容都可以从MockBackend
导入。您对component.ngOnInit
的使用仍然是相同的。
另外请注意,您无需致电fixture.detectChanges()
。当你调用{{1}}
另见:
答案 1 :(得分:2)
非常感谢@peeskillet帮助我找到答案..
import {APP_BASE_HREF} from '@angular/common';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {AppModule} from '../../../app.module';
import {persons} from '../../../data/persons';
import {Route1ListComponent} from './route1-list.component';
// HTTP mocking imports
import {BaseRequestOptions, Http, Response, ResponseOptions} from '@angular/http';
import {MockBackend, MockConnection} from '@angular/http/testing';
describe('route1-list.component.ts', () => {
let fix: ComponentFixture<Route1ListComponent>;
let instance: Route1ListComponent;
let injector: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [AppModule],
providers: [{provide: APP_BASE_HREF, useValue: '/'},
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (pBackend: MockBackend, pOptions: BaseRequestOptions) => {
return new Http(pBackend, pOptions);
},
deps: [MockBackend, BaseRequestOptions]
}]
}).compileComponents()
.then(() => {
fix = TestBed.createComponent(Route1ListComponent);
instance = fix.componentInstance;
injector = fix.debugElement.injector;
});
}));
it('should instantiate component', () => {
expect(instance).toEqual(jasmine.any(Route1ListComponent));
});
it('should have expected text', () => {
let el = fix.debugElement.query(By.css('section.route1-list')).nativeElement;
expect(el.textContent).toMatch(/route 1 list view/i, 'should have expected text');
});
it('ngOnInit()', async(() => {
let backend = injector.get(MockBackend);
backend.connections.subscribe(
(connection: MockConnection) => {
connection.mockRespond(new Response(
new ResponseOptions({
body: persons
}
)));
});
fix.detectChanges(); // Calls instance.ngOnInit()
expect(instance.persons.length).toBe(3);
}));
it('ngOnInit() failure', async(() => {
let backend = injector.get(MockBackend);
backend.connections.subscribe(
(connection: MockConnection) => {
connection.mockError(new Error('error'));
});
fix.detectChanges(); // Calls instance.ngOnInit()
expect(instance.persons).toBeUndefined();
}));
});
请注意,在撰写本文时,Angular2文档位于..
https://angular.io/docs/ts/latest/api/http/testing/index/MockBackend-class.html
https://angular.io/docs/ts/latest/api/http/testing/index/MockConnection-class.html
似乎错了。
当我使用文档中详述的Injector.resolveAndCreate
时,我收到错误:
财产&#39; resolveAndCreate&#39;类型为#in; Injector&#39;。
为了解决这个问题,我必须根据@peeskillet提供的答案来回答