是否可以像我们在 Angular 2 中测试属性指令一样对结构指令进行单元测试

Posted

技术标签:

【中文标题】是否可以像我们在 Angular 2 中测试属性指令一样对结构指令进行单元测试【英文标题】:Is it possible to unit test a structural directive the way we test an attribute directive in angular 2 【发布时间】:2019-01-21 04:07:55 【问题描述】:

我的项目中有属性和结构指令。我可以通过创建一个测试组件并在其模板中使用属性指令来测试属性指令。

@Component(
    template: `<input [myAttrDir]="prop1: val1, prop2: val2"/>`
)
export class TestComponent 


@Directive(
    selector: '[myAttrDir]'
)
export class MyAttrDirective 
    @Input('myAttrDir') testProp;

测试模块如下:

TestBed.configureTestingModule(
    declarations: [MyAttrDirective, TestComponent]
)

我通过这种方式掌握指令:

fixture = TestBed.createComponent(TestComponent)
directive = fixture.debugElement.query(By.directive(MyAttrDirective))

我能够得到属性指令的实例。 但是,当我尝试以相同的方式测试结构指令时,我得到指令的空值。 我也检查了官方文档,只发现了属性指令的单元测试。结构指令测试方法在任何地方都没有给出。

@Component(
    template: `<input *myStrucDir="prop1: val1, prop2: val2"/>`
)
export class TestComponent 

@Directive(
    selector: '[myStrucDir]'
)
export class MyStrucDirective 
    @Input set myStrucDir(data);
    constructor(
        private templateRef: TemplateRef<any>,
        private vcr: ViewContainerRef,
        private cfr: ComponentFactoryResolver,
        private el: ElementRef) 

    

TestBed.configureTestingModule(
    declarations: [MyStrucDirective, TestComponent]
)
fixture = TestBed.createComponent(TestComponent)
directive = fixture.debugElement.query(By.directive(MyStrucDirective))

是否可以以任何方式测试结构指令?

【问题讨论】:

你想达到什么目的?单元测试应该是关于测试一个单元:你不应该在你的组件测试中请求指令。 它是仅用于指令的单元测试用例文件。我只会更改测试组件中的数据,并查看指令是否按照应有的方式运行。这种方式在angular.io的官方文档中给出了 您应该在指令规范文件中测试它:您测试指令是否按照您的预期执行。在您的组件中,您测试您的组件的行为是否符合您的预期。 我也有同样的问题。看起来你不能查询它。你已经设法解决这个问题了吗? 【参考方案1】:

我遇到了同样的问题,但我知道为什么 debugElement.query(By.directive(MyStrucDirective)) 不适用于结构指令。

结构指令应用于模板 (&lt;ng-template&gt;) 而不是元素。这意味着,它们不绑定到任何DebugElement,而是绑定到DebugNode。这是一个很小的差异,但解释了为什么找不到它。

要查找实例,您必须进行不同的查询:

# Angular 8.1 or below
debugElement.queryAllNodes(debugNode => debugNode.providerTokens.includes(MyStrucDirective))[0];

# Angular 8.2
debugElement.queryAllNodes(By.directive(MyStrucDirective))[0];

【讨论】:

也许你知道如何在调用 createEmbeddedView 和 clear 方法时挂断一个间谍?在 ViewContainerRef 上

以上是关于是否可以像我们在 Angular 2 中测试属性指令一样对结构指令进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 覆盖组件

如何使用innerHTML在angular 2中附加HTML内容

Angular2:我们可以在模板中插入哪些表达式

是否可以升级 angularjs 属性指令以在 Angular 4 中使用?

如何创建像 Angular 2 那样的模板变量?

Angular 2 有条件地添加属性指令