如何使用@input alias对Angular指令进行单元测试
我想根据用户的角色显示/隐藏元素(例如,一些按钮应该只对管理员可见)。这可以通过*ngIf实现,但我相信更好的方法是一种指导:如何使用@input alias对Angular指令进行单元测试,angular,unit-testing,karma-jasmine,angular-directive,Angular,Unit Testing,Karma Jasmine,Angular Directive,我想根据用户的角色显示/隐藏元素(例如,一些按钮应该只对管理员可见)。这可以通过*ngIf实现,但我相信更好的方法是一种指导: import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; import { AuthService } from '../services/auth.service'; @Directive({ selector: '[appHasRole]', }) ex
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { AuthService } from '../services/auth.service';
@Directive({
selector: '[appHasRole]',
})
export class HasRoleDirective {
constructor(private auth: AuthService, private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) {}
@Input() set appHasRole(role: string) {
if (this.checkRole(role)) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
checkRole(role: string): boolean {
return this.auth.getRole() === role;
}
}
用这种方法
尝试2:
<div *appHasRole="'admin'">
@Component({
template: `<div *appHasRole="'admin'" class="test"></div>`,
})
class TestComponent {
@ViewChild(HasRoleDirective) directive: HasRoleDirective;
}
beforeEach(async(() => {
fixture = TestBed.configureTestingModule({
declarations: [HasRoleDirective, TestComponent],
providers: [AuthService, HasRoleDirective, TemplateRef, ViewContainerRef],
}).createComponent(TestComponent);
testDirective = new HasRoleDirective(new AuthService(), new TemplateRef(), new ViewContainerRef());
}))
@Component({
template: `<div *appHasRole="'admin'"></div>`,
})
class TestComponent {
@ViewChild(HasRoleDirective) directive: HasRoleDirective;
}
let directive: DebugElement;
let testComponent: TestComponent;
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [HasRoleDirective, TestComponent],
imports: [HttpClientModule, RouterTestingModule],
providers: [HasRoleDirective, TemplateRef, ViewContainerRef],
}).createComponent(TestComponent);
fixture.detectChanges();
testComponent = fixture.componentInstance;
directive = fixture.debugElement.query(By.directive(HasRoleDirective));
console.log(directive);
});
@Component({
template: `<div *appHasRole="'admin'" class="test"></div>`,
})
class TestComponent {
@ViewChild(HasRoleDirective) directive: HasRoleDirective;
}
let directive: DebugElement;
let testComponent: TestComponent;
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [HasRoleDirective, TestComponent],
imports: [HttpClientModule, RouterTestingModule],
providers: [HasRoleDirective, TemplateRef, ViewContainerRef],
}).createComponent(TestComponent);
fixture.detectChanges();
testComponent = fixture.componentInstance;
directive = fixture.debugElement.query(By.css('.test'));
console.log(directive);
});
@组件({
模板:``,
})
类TestComponent{
@ViewChild(HasRoleDirective)指令:HasRoleDirective;
}
let指令:DebugElement;
let testComponent:testComponent;
在每个之前(()=>{
fixture=TestBed.configureTestingModule({
声明:[HasRoleDirective,TestComponent],
导入:[HttpClientModule,RouterTestingModule],
提供者:[HasRoleDirective、TemplateRef、ViewContainerRef],
}).createComponent(TestComponent);
fixture.detectChanges();
testComponent=fixture.componentInstance;
directive=fixture.debugElement.query(By.directive(HasRoleDirective));
console.log(指令);
});
该指令始终为空,这会阻止进一步的测试。即使我尝试使用助手类访问它:
尝试3:
<div *appHasRole="'admin'">
@Component({
template: `<div *appHasRole="'admin'" class="test"></div>`,
})
class TestComponent {
@ViewChild(HasRoleDirective) directive: HasRoleDirective;
}
beforeEach(async(() => {
fixture = TestBed.configureTestingModule({
declarations: [HasRoleDirective, TestComponent],
providers: [AuthService, HasRoleDirective, TemplateRef, ViewContainerRef],
}).createComponent(TestComponent);
testDirective = new HasRoleDirective(new AuthService(), new TemplateRef(), new ViewContainerRef());
}))
@Component({
template: `<div *appHasRole="'admin'"></div>`,
})
class TestComponent {
@ViewChild(HasRoleDirective) directive: HasRoleDirective;
}
let directive: DebugElement;
let testComponent: TestComponent;
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [HasRoleDirective, TestComponent],
imports: [HttpClientModule, RouterTestingModule],
providers: [HasRoleDirective, TemplateRef, ViewContainerRef],
}).createComponent(TestComponent);
fixture.detectChanges();
testComponent = fixture.componentInstance;
directive = fixture.debugElement.query(By.directive(HasRoleDirective));
console.log(directive);
});
@Component({
template: `<div *appHasRole="'admin'" class="test"></div>`,
})
class TestComponent {
@ViewChild(HasRoleDirective) directive: HasRoleDirective;
}
let directive: DebugElement;
let testComponent: TestComponent;
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [HasRoleDirective, TestComponent],
imports: [HttpClientModule, RouterTestingModule],
providers: [HasRoleDirective, TemplateRef, ViewContainerRef],
}).createComponent(TestComponent);
fixture.detectChanges();
testComponent = fixture.componentInstance;
directive = fixture.debugElement.query(By.css('.test'));
console.log(directive);
});
@组件({
模板:``,
})
类TestComponent{
@ViewChild(HasRoleDirective)指令:HasRoleDirective;
}
let指令:DebugElement;
let testComponent:testComponent;
在每个之前(()=>{
fixture=TestBed.configureTestingModule({
声明:[HasRoleDirective,TestComponent],
导入:[HttpClientModule,RouterTestingModule],
提供者:[HasRoleDirective、TemplateRef、ViewContainerRef],
}).createComponent(TestComponent);
fixture.detectChanges();
testComponent=fixture.componentInstance;
directive=fixture.debugElement.query(By.css('.test'));
console.log(指令);
});
谁能给我一个提示吗?你想测试什么?指令还是组件?也可能有帮助,dom在我尝试测试指令时,在
ngAfterViewInit
之后才会初始化。我不知道ngAfterViewInit能帮我什么忙?不应该考虑DOM中的更改吗?非常感谢你的帮助!