Angular 8 指令用于基于角色的视图

Angular 8 Directive for role based views

我正在查看这个基于用户角色显示组件的示例: https://blog.strongbrew.io/display-a-component-based-on-role/

我的代码无法编译,因为 has-role.directive.spec.ts 中的构造函数中缺少参数。从 has-role.directive.ts 开始,它需要 3 个参数:来自 angular 核心的 ViewContainerRef 和 TemplateRef,以及用于获取用户角色的服务。

has-role.directive.ts

    constructor(
    private viewContainerRef: ViewContainerRef,
    private templateRef: TemplateRef<any>,
    private authenticationService: AuthenticationService)

但是在示例教程中,它是这样使用的: has-role.directive.spec.ts

 describe('HasRoleDirective', () => {
  it('should create an instance', () => {
    const directive = new HasRoleDirective();
    expect(directive).toBeTruthy();
  });
});

示例中的这个如何工作,但对我来说它抱怨缺少参数?


更新:

正如 Michał 所建议的,我创建了 classes 以添加到构造函数中:

class TestViewContainerRef extends ViewContainerRef {
    element: ElementRef<any>;
    injector: Injector;
    parentInjector: Injector;
    clear(): void {
        throw new Error('Method not implemented.');
    }
    get(index: number): ViewRef {
        throw new Error('Method not implemented.');
    }
    length: number;
    createEmbeddedView<C>(templateRef: TemplateRef<C>, context?: C, index?: number): EmbeddedViewRef<C> {
        throw new Error('Method not implemented.');
    }
    createComponent<C>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][], ngModule?: NgModuleRef<any>): ComponentRef<C> {
        throw new Error('Method not implemented.');
    }
    insert(viewRef: ViewRef, index?: number): ViewRef {
        throw new Error('Method not implemented.');
    }
    move(viewRef: ViewRef, currentIndex: number): ViewRef {
        throw new Error('Method not implemented.');
    }
    indexOf(viewRef: ViewRef): number {
        throw new Error('Method not implemented.');
    }
    remove(index?: number): void {
        throw new Error('Method not implemented.');
    }
    detach(index?: number): ViewRef {
        throw new Error('Method not implemented.');
    }
}

let viewContainerRefMock = {
  viewContainerRef: TestViewContainerRef
};

describe('HasRoleDirective', () => {
  it('should create an instance', () => {
    const directive = new HasRoleDirective(viewContainerRefMock, templateRefMock, authenticationServiceMock);
    expect(directive).toBeTruthy();
  });
});

现在它抱怨我的 class:

只需为构造函数参数创建模拟 类,根据您的需要扩展抽象。例如。在 has-role.directive.spec.ts 创建

class TestViewContainerRef extends ViewContainerRef { }
class TestTemplateRef extends TemplateRef<eny> { }
class TestAuthenticationService extends AuthenticationService { }

然后从接口实现所有需要的方法。他们可以有 body 像 throw new Error("Method not implemented."); - 不管怎样,你不会在这样的测试中使用它。并为每个创建 object 并放入 HasRoleDirective 构造函数。

好吧,很明显您遗漏了错误消息中描述的一些参数。在您的应用程序中使用该指令时,angular 会创建这 3 个依赖项并将它们注入到您的指令中。

在您的示例中,您正在测试中创建指令的实例。 Angular不能注入那些依赖,因为没有Angular,是测试。由于 Angular 没有提供它们,您应该手动提供它们。这是解释 here.

您提到的博客不需要它们的原因是该博客没有对其进行单元测试。