角度指令 ViewContainerRef 测试模拟

Ale*_*sky 9 jasmine angular

鉴于注入了ViewContainerRef 的用于动态组件加载的指令:

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[fooHost]'
})
export class FooDirective {
  constructor(public viewContainerRef: ViewContainerRef) {}
}
Run Code Online (Sandbox Code Playgroud)

您将如何ViewContainerRef在单元测试中注入实例或模拟:

import { FooDirective } from './foo.directive';

describe('FooDirective', () => {
  it('should create an instance', () => {
    const directive = new FooDirective();
    expect(directive).toBeTruthy();
  });
});
Run Code Online (Sandbox Code Playgroud)

由于以下错误,此最基本的测试失败:

未提供“viewContainerRef”的参数。

测试指南不包括此也不存在出现任何测试模块具体用于创建的一个实例ViewContainerRef

这是很简单的创建一个存根@ComponentTestBed.createComponent和通过任何夹具或组件实例作为ViewContainerRef

import { FooDirective } from './foo.directive';
import { ViewContainerRef, Component } from '@angular/core';
import { TestBed, async } from '@angular/core/testing';

@Component({ selector: 'app-stub', template: '' })
class StubComponent {}

describe('LightboxDirective', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({ declarations: [StubComponent] }).compileComponents();
  }));

  it('should create an instance', () => {
    const fixture = TestBed.createComponent(StubComponent);
    const component = fixture.debugElement.componentInstance;

    const directive = new FooDirective(component);
    expect(directive).toBeTruthy();
  });
});
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,应该将什么作为ViewContainerRef、thefixture.debugElement.componentInstancefixture.debugElement.nativeElement其他东西传递?

谢谢!

Dan*_*lis 7

ViewContainerRef是一个抽象类,从@angular/core. 因为是抽象类,所以不能直接实例化。但是,在您的测试类中,您可以简单地创建一个新类,该类包含extendsViewContainerRef,并实现所有必需的方法。然后,您可以简单地实例化 TestViewContainerRef 的一个新实例,并将其传递到您的测试/规范中的 FooDirective 构造函数中。像这样:

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

}
Run Code Online (Sandbox Code Playgroud)

提示:我在 Mac 上使用 VS Code。当我创建类 stub 时class TestViewContainerRef extends ViewContainerRef { },代码给了我一个非常有用的代码提示来实现所有抽象方法。我用它来自动生成上面的代码。其他 IDE 可能会提供类似的功能来帮助流程更顺畅。您可以在此处复制/粘贴代码以在您的测试/规范类中使用。但是,Angular 可能会随时选择更改 ViewContainerRef 抽象类的接口,因此如果您确实复制了上面的这段代码,请注意这样做后果自负。

这是我如何使用它来让我的 Angular 测试通过的示例:

import { ModalHostDirective } from './modal-host.directive';
import { ViewContainerRef } from '@angular/core';

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

}

describe('ModalHostDirective', () => {
  it('should create an instance', () => {
    const directive = new ModalHostDirective(new TestViewContainerRef());
    expect(directive).toBeTruthy();
  });
});
Run Code Online (Sandbox Code Playgroud)

免责声明:就实际针对这个 TestViewContainerRef 编写测试而言,好吧......我把它留给你们所有人。但这至少可以满足ng test

干杯!

  • 这就是我解决问题的方法:/sf/ask/4574879011/ (2认同)