我有一个 Angular 独立组件,它有一个子独立组件。 在我的单元测试中,我想模拟所述子组件。当我检查模拟组件是否通过fixture.debugElement 渲染时,我看到模拟组件已被使用。 但是当我尝试引用 ViewChild 时,它总是未定义。
有什么想法吗?
角度版本:17.1.0
相关代码如下:
@Component({
selector: 'child',
standalone: true,
template: 'Child',
})
export class ChildComponent {}
@Component({
selector: 'app-root',
standalone: true,
imports: [ChildComponent],
template: '<child></child>'
})
export class AppComponent implements AfterViewInit {
@ViewChild(ChildComponent) child!: ChildComponent;
ngAfterViewInit(): void {
// On serving the app this.child is defined
// In the tests this.child is undefined
console.log(this.child);
}
}
@Component({
selector: 'child',
template: `Mocked child`,
standalone: true,
})
class MockChildComponent {}
beforeEach(waitForAsync(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent]
})
.overrideComponent(AppComponent, {
set: {
imports: [MockChildComponent]
}
})
.compileComponents();
fixture = TestBed.createComponent(AppComponent);
appComponent = fixture.componentInstance;
fixture.detectChanges();
}));
当我删除
overrideComponent
时,我确实获得了对 ViewChild 的定义引用。但当然,它不会被嘲笑。
// OK
it('should have the rendered mocked child element', () => {
expect(
fixture.debugElement.query(By.css('child')).nativeElement.innerHTML,
).toContain('Mocked child');
});
// Fail: Expected undefined to be truthy.
it('should have the mocked child component', () => {
expect(appComponent.child).toBeTruthy();
});
当然,我在发布此内容后立即修复了它。我是我自己的橡皮鸭..我正在用解决方案编辑帖子,以防其他人遇到这个问题。
为了获得正确的参考,我将 app.component.ts 中的模板更改为
<child #child></child>
:
@Component({
selector: 'app-root',
standalone: true,
imports: [ChildComponent],
template: '<child #child></child>' // Was: <child></child>
})
并更改 ViewChild 以引用寺庙 ate 变量而不是组件。
@ViewChild('child') child!: ChildComponent;
// @ViewChild(ChildComponent) child!: ChildComponent;
现在它按预期工作了。
编辑:将解决方案移至答案帖子,而不是在问题中编辑它。