I have both attribute and structural directives in my project. I am able to test the attribute directive by creating a test component and using the attribute directive in it's template.
@Component({
template: `<input [myAttrDir]="{prop1: val1, prop2: val2}"/>`
})
export class TestComponent {
}
@Directive({
selector: '[myAttrDir]'
})
export class MyAttrDirective {
@Input('myAttrDir') testProp;
}
The testing module looks like:
TestBed.configureTestingModule({
declarations: [MyAttrDirective, TestComponent]
})
I get hold of directive this way:
fixture = TestBed.createComponent(TestComponent)
directive = fixture.debugElement.query(By.directive(MyAttrDirective))
I am able to get the instance of attribute directive. However when I try this same way to test structural directive, I get null value of directive. I have checked out official documentation as well and only found the unit testing of attribute directive. The structural directive testing methodology is not given anywhere.
@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))
Is it possible to test structural directive in any way?
There are two types of directives in Angular. Attribute directives modify the appearance or behavior of DOM elements. Structural directives add or remove elements from the DOM.
we cannot use two structural directives on same element. Structural directives like ngfor can do complex things with the host element and its childrens. When two directives placed on same element we cannot decide which one takes precedence i.e., which should execute first *ngIf or *ngFor?
Angular attribute directives are a number of built-in directives that we can add to our HTML elements that give them a dynamic behavior. In summary, an attribute directive changes the appearance or behavior of a DOM element.
I had the same issue, but I figured out why debugElement.query(By.directive(MyStrucDirective))
does NOT work for structural directives.
Structural directives are applied to templates (<ng-template>
) instead of elements. This means, that they are not bound to any DebugElement
, but rather to a DebugNode
. That is a small difference, but explains why it is not found.
To find the instance, you have to query differently:
# Angular 8.1 or below
debugElement.queryAllNodes(debugNode => debugNode.providerTokens.includes(MyStrucDirective))[0];
# Angular 8.2
debugElement.queryAllNodes(By.directive(MyStrucDirective))[0];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With