【发布时间】:2017-08-24 07:55:16
【问题描述】:
正如上面的标题问题 - 是否可以将另一个服务实例注入特定的测试功能?我的意思是,在测试服中,我在 beforeEach 方法中注入了一些服务。
创建存根:
let userServiceStub = {
hasReadPermissions() { return true; },
isUserInformationAvailable() { return true; },
isUserRequestForbidden() { return true; }
};
在beforeEach方法中配置测试模块:
TestBed.configureTestingModule({
declarations: [
SomeComponent
],
providers: [{ provide: UserService, useValue: userServiceStub },
{ provide: AnotherService, useValue: anotherServiceStub }],
schemas: [ NO_ERRORS_SCHEMA ]
}).compileComponents();
然后我要测试用例:
首先我想使用在 TestBed 中注入的服务存根
it('should render topbar when user has read permissions', () => {
let topbar = debugElement.query(By.css('topbar'));
expect(topbar).toBeTruthy();
});
我想使用同一服务的另一个存根的第二个地方:
let anotherUserServiceStub = {
hasReadPermissions() { return false; },
isUserInformationAvailable() { return false; },
isUserRequestForbidden() { return true; }
};
it('should render appropriate message when user has not read permissions',
inject([UserService], (userService: UserService) => { <--- how to inject another user service stub here?
let message = debugElement.query(By.css('h2'));
expect(message).toBe('you have no permissions');
}));
或者也许我试图以不恰当的方式做这件事?请指出正确的方法。
[[编辑]]
部分组件逻辑:
dataUnavailable: boolean = false;
noPermissions: boolean = false;
constructor(private toastr: ToastsManager,
vRef: ViewContainerRef,
private userService: UserService,
private router: Router) {
this.toastr.setRootViewContainerRef(vRef);
}
ngOnInit(): void {
if (!this.isUserInformationAvailable()) {
if (this.isUserRequestForbidden()) {
this.noPermissions = true;
} else {
this.dataUnavailable = true;
this.toastr.error("An error occured while getting data from server.");
}
}
}
hasUserReadPermissions(): boolean {
return this.userService.hasReadPermissions();
}
模板:
<ng-container *ngIf="hasUserReadPermissions()">
<topbar></topbar>
<main-menu></main-menu>
<router-outlet></router-outlet>
</ng-container>
<div class="row" *ngIf="dataUnavailable">
<div class="col-sm-12">
<h2 class="text-center rcm-bold-message">Server data is not available.</h2>
</div>
</div>
<div class="row" *ngIf="noPermissions">
<div class="col-sm-12">
<h2 class="text-center rcm-bold-message">You do not have sufficient permissions.</h2>
</div>
</div>
【问题讨论】:
-
Mhhhhh,你为什么要这样做?服务应该是
Singleton,所以你不想在你的应用程序中使用不同的实例,所以没有理由像这样测试它。顺便说一句,如果您覆盖服务,请使用useClass而不是useValue,因为useClass将确保解决依赖关系。 -
我想这样做以向不同的测试用例提供另一种服务方法结果。尝试测试组件行为,以防用户具有读取权限(hasReadPermissions() { return true; })而没有读取权限(hasReadPermissions() { return false; })。有没有更好的解决方案?
-
啊,好吧,现在我明白了;)好吧,基本上你在这个测试中测试你的组件,对吧?所以你为它存根你的服务,因为实际的服务在这个测试中并不重要,但它仍然会被使用。但这并不一定意味着您必须使用存根服务的返回值。例如,如果您在您正在测试的
h2元素上有一个*ngIf,并且这个*ngIf* depends on the return value of your service method, just ignore that fact and mock the property which is used in your*ngIf 直接。希望我很清楚。 -
如果您将要测试的组件模板部分添加到您的问题中,如果您愿意,我可以通过答案更好地解释它。
-
好的,谢谢。被测组件已添加到帖子中。
标签: angular unit-testing testing