Unit testing: directives on ng-template present but not detectable with By.directive
- Dominant language
- TypeScript
- Stars
- 101k
- Forks
- 27.5k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 288
Description
### Which @angular/* package(s) are the source of the bug?
core
### Is this a regression?
No
### Description
Directives added to `ng-template` (as describe in [Angular's guide to dynamic components](https://angular.io/guide/dynamic-component-loader#the-anchor-directive)) don't seem to be detectable using `DebugElement.query(By.directive([directive]))`.
For example:
```
@Directive({
selector: '[fooHost]',
})
class FooDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
@Component({
template: '',
})
class TestHostComponent {
@ViewChild(FooDirective, { static: true }) fooDirective!: FooDirective;
}
describe('injected directive', () => {
let fixture: ComponentFixture;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [FooDirective, TestHostComponent],
}).compileComponents();
fixture = TestBed.createComponent(TestHostComponent);
});
afterEach(() => {
fixture.nativeElement.remove();
// Get a fresh TestBed configuration between tests.
TestBed.resetTestingModule();
});
...
```
If the directive is queried, no directive will be found:
```
it('FooDirective undetectable using query(By.directive)', () => {
fixture.detectChanges();
const fooDirective = fixture.debugElement.query(By.directive(FooDirective));
expect(fooDirective).toBeNull();
});
```
Yet if we check the TestHostComponent's `fooDirective`, we can see that `FooDirective` was correctly added, and properties like its `viewContainerRef` have been defined:
```
it('FooDirective gets viewContainerRef', () => {
const fooDirective = fixture.componentInstance.fooDirective;
expect(fooDirective.viewContainerRef).toBeDefined();
});
```
(Notice that `fixture.detectChanges()` was not necessary.)
### Please provide a link to a minimal reproduction of the bug
https://stackblitz.com/edit/angular-unit-testing-examples-tpfzzf?file=src%2Fapp%2Fdemo.cmpnt.spec.ts
### Please provide the exception or error you saw
```true
Not applicable
```
### Please provide the environment you discovered this bug in (run `ng version`)
```true
This was documented in Stackblitz, where no console is available to run Angular's `ng version`. See the Dependencies in Stackblitz. Angular 14.0.6 was installed. It also appears locally in my older Angular setup:
Angular CLI: 13.3.3
Node: 16.13.0
Package Manager: npm 8.3.0
OS: darwin x64
Angular: 13.3.3
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1303.3
@angular-devkit/build-angular 13.3.3
@angular-devkit/core 13.3.3
@angular-devkit/schematics 13.3.3
@angular/fire 7.3.0
@schematics/angular 13.3.3
rxjs 6.6.7
typescript 4.5.5
```
### Anything else?
_No response_
Contributor guide
Research direction
Start with the reproduction in src/app/demo.cmpnt.spec.ts and the Angular core testing APIs used by DebugElement.query(By.directive). Reproduce the ng-template case, compare directive discovery with the working ViewChild lookup, and inspect the related core testing implementation. Done means a regression test demonstrates that directives on ng-template are discoverable through By.directive without breaking existing queries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- angular, typescript
- Domain
- frontend, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100