给出用于Dynamic Component Loading且注入了ViewContainerRef的指令:
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[fooHost]'
})
export class FooDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
如何在单元测试中注入ViewContainerRef
的实例或模拟:
import { FooDirective } from './foo.directive';
describe('FooDirective', () => {
it('should create an instance', () => {
const directive = new FooDirective();
expect(directive).toBeTruthy();
});
});
此最基本的测试由于以下错误而失败:
未提供'viewContainerRef'的参数。
testing guide并未涵盖这一点,也似乎没有专门用于创建ViewContainerRef
实例的测试模块。
这是简单的吗,例如用@Component
创建存根TestBed.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();
});
});
如果是这种情况,应该以{{1}},ViewContainerRef
或fixture.debugElement.componentInstance
或其他形式传递什么?
谢谢!
答案 0 :(得分:4)
ViewContainerRef
是从@angular/core
导入的抽象类。由于它是抽象类,因此无法直接实例化。但是,在测试类中,您可以简单地创建一个extends
ViewContainerRef的新类,并实现所有必需的方法。然后,您可以简单地实例化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.");
}
}
提示:我在Mac上使用VS Code。当我创建类存根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();
});
});
免责声明:就实际针对此TestViewContainerRef编写测试而言,...我将其留给大家。但这至少满足ng test
。
干杯!