Angular 15中BreakpointObserver单元测试失败,如何验证mobileMode?
正确编写Angular BreakpointObserver单元测试的方法
你的测试失败原因是:Angular的BreakpointObserver在单元测试环境中不会真实监听浏览器窗口尺寸变化,直接修改window.innerWidth或触发resize事件无法触发它的状态更新。需要通过模拟BreakpointObserver的行为来实现测试。
步骤1:在测试配置中提供Mock的BreakpointObserver
在组件的测试文件中,使用TestBed配置时,替换真实的BreakpointObserver为模拟对象:
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { BreakpointObserver, BreakpointState, Breakpoints } from '@angular/cdk/layout'; import { MyComponent } from './my.component'; import { of } from 'rxjs'; describe('MyComponent', () => { let component: MyComponent; let fixture: ComponentFixture<MyComponent>; let breakpointObserverSpy: jasmine.SpyObj<BreakpointObserver>; beforeEach(async () => { // 创建BreakpointObserver的spy对象 breakpointObserverSpy = jasmine.createSpyObj('BreakpointObserver', ['observe']); await TestBed.configureTestingModule({ declarations: [MyComponent], providers: [ { provide: BreakpointObserver, useValue: breakpointObserverSpy } ] }).compileComponents(); fixture = TestBed.createComponent(MyComponent); component = fixture.componentInstance; });
步骤2:编写测试用例,模拟匹配XSmall断点的情况
在测试中,让observe方法返回一个Observable,发出matches: true的BreakpointState:
it('should set mobileMode to true when screen is extra small', () => { // 模拟observe方法返回匹配XSmall的状态 breakpointObserverSpy.observe.and.returnValue( of({ matches: true } as BreakpointState) ); // 触发ngOnInit(首次detectChanges会调用组件初始化生命周期) fixture.detectChanges(); expect(component.mobileMode).toBeTrue(); // 验证observe方法是否被正确调用,传入了XSmall断点参数 expect(breakpointObserverSpy.observe).toHaveBeenCalledWith([Breakpoints.XSmall]); });
步骤3:额外测试不匹配的情况(可选)
你也可以添加测试验证非小屏时mobileMode为false:
it('should set mobileMode to false when screen is not extra small', () => { breakpointObserverSpy.observe.and.returnValue( of({ matches: false } as BreakpointState) ); fixture.detectChanges(); expect(component.mobileMode).toBeFalse(); });
关键说明
- 不要直接操作
window对象来测试BreakpointObserver,因为Angular的CDK布局模块在测试环境中不会依赖真实的浏览器窗口尺寸。 - 使用Jasmine的
createSpyObj创建模拟对象,控制observe方法的返回值,这样可以精准控制测试场景,避免依赖外部环境。
内容的提问来源于stack exchange,提问作者Sun
相关产品推荐
相关产品推荐

