为什么我在模拟 ViewChild 时对 ViewChild 的引用未定义

问题描述 投票:0回答:1

我有一个 Angular 独立组件,它有一个子独立组件。 在我的单元测试中,我想模拟所述子组件。当我检查模拟组件是否通过fixture.debugElement 渲染时,我看到模拟组件已被使用。 但是当我尝试引用 ViewChild 时,它总是未定义。

有什么想法吗?

角度版本:17.1.0

相关代码如下:

child.component.ts

@Component({
  selector: 'child',
  standalone: true,
  template: 'Child',
})
export class ChildComponent {}

app.component.ts

@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);
  }
}

app.component.spec.ts

模拟子组件

@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();
  });
angular testing mocking viewchild angular-standalone-components
1个回答
0
投票

解决了

当然,我在发布此内容后立即修复了它。我是我自己的橡皮鸭..我正在用解决方案编辑帖子,以防其他人遇到这个问题。

为了获得正确的参考,我将 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;

现在它按预期工作了。

编辑:将解决方案移至答案帖子,而不是在问题中编辑它。

© www.soinside.com 2019 - 2024. All rights reserved.