MatMenuItemHarness无法识别菜单项问题求助
报错信息
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
相关产品推荐
相关产品推荐

