You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MatMenuItemHarness无法识别菜单项问题求助

MatMenuItemHarness无法定位mat-menu-item元素的问题排查

报错信息

Error: Failed to find element matching one of the following queries:
(MatMenuItemHarness with host element matching selector: ".mat-mdc-menu-item")

相关HTML代码

<mat-menu #menu="matMenu" class="user-menu">
  <button
    mat-menu-item
    class="edit-profile-button"
    aria-label="Edit profile button"
    [routerLink]="['../edit-profile']"
    >Edit Profile
  </button>
  <button
    mat-menu-item
    aria-label="Logout button"
    class="logout-button"
    (click)="logout()"
    >Logout
  </button>
</mat-menu>

初始测试代码

describe('logout button', () => {
  it('should emit the logoutUser event when clicked', async () => {
    spyOn(component.logoutUser, 'emit');
    component.loggedOnUser$ = of(new User());
    const userMenu = await loader.getHarness(MatMenuHarness);
    await userMenu.open();
    const btn = await loader.getHarness(MatMenuItemHarness);
    await btn.click();
    expect(component.logoutUser.emit).toHaveBeenCalled();
  });
});

验证菜单项存在的测试代码

describe('logout button', () => {
  it('should emit the logoutUser event when clicked', async () => {
    component.loggedOnUser$ = of(new User());
    const userMenu = await loader.getHarness(MatMenuHarness);
    await userMenu.open();
    const items = await userMenu.getItems();
    expect(items.length).toBe(2) // 此断言通过
    expect((await loader.getAllHarnesses(MatMenuItemHarness)).length).toBe(2); // 此断言失败
  });
});

测试模块配置

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [
      ToolbarComponent,
      RouterTestingModule,
      MatMenuModule,
      MatButtonModule,
      BrowserAnimationsModule
    ]
  })
  fixture = TestBed.createComponent(ToolbarComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
  loader = TestbedHarnessEnvironment.loader(fixture);
});

问题原因

核心问题是Angular Material版本的组件样式类不匹配:

  • MatMenuItemHarness 默认查找的选择器是 .mat-mdc-menu-item,这是Angular Material的MDC(Material Design Components)版本组件的样式类。
  • 但你的代码中使用的是旧版非MDC的mat-menu-item,对应的样式类是 .mat-menu-item,而非.mat-mdc-menu-item,所以Harness无法匹配到元素。

另外,userMenu.getItems()能返回正确数量,是因为这个方法内部通过菜单自身逻辑获取子项,不依赖Harness的选择器,所以能正常工作。

解决办法

有两种方案可选:

方案1:切换到MDC版本的Harness

如果项目已升级到Angular Material的MDC版本(15+默认是MDC版本),确保导入正确的Harness:

// 导入MDC版本的MenuItemHarness
import { MatMenuItemHarness } from '@angular/material/menu/testing';

同时确认测试模块中导入的是MatMenuModule(MDC版本的菜单模块)。

方案2:使用旧版非MDC的Harness

如果项目仍在使用非MDC版本的Angular Material,需要导入旧版Harness:

// 导入非MDC版本的MenuItemHarness
import { MatMenuItemHarness } from '@angular/material/legacy-menu/testing';

旧版Harness的选择器是.mat-menu-item,和你的组件样式类匹配,就能正常定位元素。同时测试模块中要导入MatLegacyMenuModule而非MatMenuModule。

内容的提问来源于stack exchange,提问作者Pablo52

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:02:49