我正在尝试为Angular组件创建一个测试,该测试的模板中包含来自Angular Material的MatMenu。我想测试该菜单中的项目。事实证明,MatMenu内部的HTML仅在打开菜单后才编译,因此我需要以某种方式在菜单触发器上调用openMenu方法。问题是我找不到在Angular测试中获取对MatMenuTrigger组件的引用的方法。对于大多数组件,当我使用例如查询它们时debugElement.queryAllNodes(By.directive(MatIcon))我得到了一个带有componentInstance属性的DebugElement,而这正是我所需要的,但是不幸的是,对于MatMenuTrigger来说,它不能那样工作。我不知道为什么,但是此代码debugElement.queryAllNodes(By.directive(MatMenuTrigger))[0].componentInstance返回的是父组件实例(与debugElement.componentInstance相同),而不是我可以用来打开菜单的MatMenuTrigger。

这是Angular测试框架中的错误还是我做错了什么?

最佳答案

您可以监视诸如MatMenuTrigger之类的closeMenu函数,该函数从触发菜单的按钮(元素)获取MatMenuTrigger的实例。

it('calls Close Menu on Cancel', () => {
  const menuTigger: MatMenuTrigger = fixture.debugElement.query(By.directive(MatMenuTrigger)).injector.get(MatMenuTrigger);
  spyOn(menuTigger, 'closeMenu');
  component.onCancel();
  expect(menuTigger.closeMenu).toHaveBeenCalledTimes(1);
});


@Component({
  selector: 'my-parent',
  templateUrl: './my-parent.component.html'
})
export class MyParentComponent {
  @ViewChild('myMenuTrigger')
  private readonly menuTrigger: MatMenuTrigger;

  public onCancel(): void {
    this.menuTrigger.closeMenu();
  }
}


<button mat-button #myMenuTrigger="matMenuTrigger" [matMenuTriggerFor]="dateMenu">
  My Menu
</button>
<mat-menu #myMenu="matMenu">
   <!-- -->
</mat-menu>

07-24 14:16