Angular 2 RC 如何对可观察对象进行单元测试
Angular 2 RC how to unit test an observable
我正在为 angular 2 RC 应用程序编写一些测试,但在测试可观察对象时遇到了一些问题。我模拟了将它的类型设置为可观察的方法,但是当被测试的单元试图订阅模拟的可观察的时,我得到一个错误 'Cannot read property 'subscribe' of undefined'
我正在测试我的 DashboardComponent
,它会注入一个 model3DService
并调用 model3DService.get3DModels()
这是一个执行 http 请求和 returns 3D 数组的可观察对象模型对象。
下面是一些示例代码:
仪表板组件
import { Model3DService } from '../../services/model3D/model3D.service';
import { ProjectService } from '../../services/project/project.service';
@Component({
selector: 'cmg-dashboard',
styles: [require('./css/dashboard.scss')],
template: require('./dashboard.html')
})
export class DashboardComponent implements OnInit {
constructor(
private projectService: ProjectService,
private model3DService: Model3DService
) { }
ngOnInit (): void {
this.model3DService.get3DModels().subscribe((res: any[]) => {
this.findProjects(res);
this.models = res;
this.projectService.isProjectSelected = true;
this.createProject(res[0]);
});
}
}
Model3DService
@Injectable()
export class Model3DService {
private models: any[] = [];
public get3DModels (): Observable<any> {
return this.http.get('../../../json/3DModel.json')
.map(( res: Response ) => {
this.models = res.json();
return this.models;
});
}
}
好的,现在我们有了待测,这是我正在写的测试。
仪表板组件规范
class MockModel3DService {
public get3DModels(): Observable<any> {
return;
}
}
describe('Dashboard Component', () => {
beforeEachProviders(() => {
return [
DashboardComponent,
provide(ProjectService, {
useClass: MockProjectService
}),
provide(Model3DService, {
useClass: MockModel3DService
})
];
});
describe('ngOnInit', () => {
it('should call model3DService.get3DModels on init', (inject([DashboardComponent], (dashboardComponent: DashboardComponent, model3DService: MockModel3DService) => {
dashboardComponent.ngOnInit();
expect(model3DService.get3DModels).toHaveBeenCalled();
})));
});
});
这个概念类似于测试 AngularJS $q
承诺。 Stubbed 方法 return 是一个可观察的模拟。该方法可以 return 一个主题,而不是 inherits Observable
但也具有 observables 和 observers 的属性。
可以为新主题提供就地模拟值,需要事先定义模拟承诺(主题与延迟共享此 属性,请参阅 )。
RxJS 4 科目有 hasObservers
方法可以避免 subscribe
间谍。 RxJS 5 主题错过了方法,但他们公开了 observers
属性.
很可能应该是这样的
let subject: Subject;
class MockModel3DService {
public get3DModels(): Observable<any> {
return subject;
}
}
...
// beforeEach(...)
subject = new Subject;
...
// it(...)
const models = ['mocked'];
dashboardComponent.ngOnInit();
expect(subject.observers.length).toBe(1);
subject.next(models);
expect(model3DService.get3DModels).toHaveBeenCalled();
expect(dashboardComponent.models).toBe(models);
...
您的 MockModel3DServic.get3DModels 没有 return 可观察值。
import { of } from 'rxjs';
class MockModel3DService {
public get3DModels(): Observable<any> {
return of(yourResponse)
}
}
我正在为 angular 2 RC 应用程序编写一些测试,但在测试可观察对象时遇到了一些问题。我模拟了将它的类型设置为可观察的方法,但是当被测试的单元试图订阅模拟的可观察的时,我得到一个错误 'Cannot read property 'subscribe' of undefined'
我正在测试我的 DashboardComponent
,它会注入一个 model3DService
并调用 model3DService.get3DModels()
这是一个执行 http 请求和 returns 3D 数组的可观察对象模型对象。
下面是一些示例代码:
仪表板组件
import { Model3DService } from '../../services/model3D/model3D.service';
import { ProjectService } from '../../services/project/project.service';
@Component({
selector: 'cmg-dashboard',
styles: [require('./css/dashboard.scss')],
template: require('./dashboard.html')
})
export class DashboardComponent implements OnInit {
constructor(
private projectService: ProjectService,
private model3DService: Model3DService
) { }
ngOnInit (): void {
this.model3DService.get3DModels().subscribe((res: any[]) => {
this.findProjects(res);
this.models = res;
this.projectService.isProjectSelected = true;
this.createProject(res[0]);
});
}
}
Model3DService
@Injectable()
export class Model3DService {
private models: any[] = [];
public get3DModels (): Observable<any> {
return this.http.get('../../../json/3DModel.json')
.map(( res: Response ) => {
this.models = res.json();
return this.models;
});
}
}
好的,现在我们有了待测,这是我正在写的测试。
仪表板组件规范
class MockModel3DService {
public get3DModels(): Observable<any> {
return;
}
}
describe('Dashboard Component', () => {
beforeEachProviders(() => {
return [
DashboardComponent,
provide(ProjectService, {
useClass: MockProjectService
}),
provide(Model3DService, {
useClass: MockModel3DService
})
];
});
describe('ngOnInit', () => {
it('should call model3DService.get3DModels on init', (inject([DashboardComponent], (dashboardComponent: DashboardComponent, model3DService: MockModel3DService) => {
dashboardComponent.ngOnInit();
expect(model3DService.get3DModels).toHaveBeenCalled();
})));
});
});
这个概念类似于测试 AngularJS $q
承诺。 Stubbed 方法 return 是一个可观察的模拟。该方法可以 return 一个主题,而不是 inherits Observable
但也具有 observables 和 observers 的属性。
可以为新主题提供就地模拟值,需要事先定义模拟承诺(主题与延迟共享此 属性,请参阅
RxJS 4 科目有 hasObservers
方法可以避免 subscribe
间谍。 RxJS 5 主题错过了方法,但他们公开了 observers
属性.
很可能应该是这样的
let subject: Subject;
class MockModel3DService {
public get3DModels(): Observable<any> {
return subject;
}
}
...
// beforeEach(...)
subject = new Subject;
...
// it(...)
const models = ['mocked'];
dashboardComponent.ngOnInit();
expect(subject.observers.length).toBe(1);
subject.next(models);
expect(model3DService.get3DModels).toHaveBeenCalled();
expect(dashboardComponent.models).toBe(models);
...
您的 MockModel3DServic.get3DModels 没有 return 可观察值。
import { of } from 'rxjs';
class MockModel3DService {
public get3DModels(): Observable<any> {
return of(yourResponse)
}
}