【问题标题】:Angular unit testing - stubbing/mocking a directive with reference in ViewChildAngular 单元测试 - 在 ViewChild 中引用/模拟指令
【发布时间】:2019-06-25 09:09:18
【问题描述】:

如何存根/模拟读取为ViewChild 的指令/组件?

例如,使用 angular.io 中的简单指令:

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  constructor() { }
}

假设我正在测试AppComponent,并使用ViewChild 读取HighlightDirective

@ViewChild(HighlightDirective) theHighlightDirective: HighlightDirective

而存根指令是:

@Directive({
  selector: '[appHighlight]'
})
export class StubbedHighlightDirective {
  constructor() { }
}

由于组件试图读取HighlightDirective,即使您在单元测试中声明StubbedHighlightDirectivetheHighlightDirective 也将是undefined

例子:

it('HighlightDirective is defined', () => {
    // This test fails
    expect(component.theHighlightDirective).toBeDefined();
});

如果您忽略 tslint 中的某些内容或使用 as 关键字,则可以解决此问题:

Version 1: Just ignore some things in tslint so compiler doesn't complain
it('HighlightDirective is defined', () => {
    // Compiler will typically complain saying that
    // StubbedHighlightDirective isn't assignable to type of HighlightDirective
    component.theHighlightDirective = new StubbedHighlightDirective();

    // this passes
    expect(component.theHighlightDirective).toBeDefined();
});

Version 2: Use "as" keyword
it('HighlightDirective is defined', () => {
    // Actually compiler will still complain with warnings
    component.theHighlightDirective = new StubbedHighlightDirective() as HighlightDirective;

    // this passes
    expect(component.theHighlightDirective).toBeDefined();
});

是否有另一种方法可以彻底清除这类 ViewChild 引用?

【问题讨论】:

  • 对不起,我不认为这是可能的

标签: angular unit-testing jasmine viewchild


【解决方案1】:

问题是您正在使用一个类来查找孩子,而该类已被您的存根替换。您可以在指令中使用匹配的exportAs 链接(docsblog post)以确保真实版本和存根具有相同的名称。

在原指令装饰器中:

@Directive({
    selector: '[appHighlight]',
    exportAs: 'appHighlight'
})
export class HighlightDirective {

在存根指令中:

@Directive({
    selector: '[appHighlight]',
    exportAs: 'appHighlight'
})
export class StubbedHighlightDirective {

然后在使用指令的模板中:

<div appHighlight #appHighlight="appHighlight">

完成所有这些后,您需要更新您的 @ViewChild 定义以使用字符串而不是类:

@ViewChild('appHighlight') theHighlightDirective: HighlightDirective

【讨论】:

    猜你喜欢
    • 2015-05-03
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 2020-11-19
    • 1970-01-01
    • 2018-07-20
    • 2016-06-11
    相关资源
    最近更新 更多