如何编写Jasmine单元测试覆盖Angular mat-autocomplete的Observable过滤逻辑
Angular中测试带pipe操作的Observable方法方案
你当前测试未覆盖pipe后续逻辑的核心原因是:Observable是懒执行的,只有当你主动订阅返回的Observable实例时,pipe中定义的操作符逻辑才会实际运行。你现有代码只调用了dataFilter()方法拿到了Observable对象,没有触发订阅,因此内部的map、过滤逻辑全程没有执行。
正确测试实现
方式1:Jasmine done回调(通用异步场景)
// 先定义测试用模拟数据源 const MOCK_DATA = [ { foo: 'Apple' }, { foo: 'Banana' }, { foo: 'Cherry' }, { foo: 'Apricot' } ]; it('should return all data when filter value is empty', (done) => { getApiSpy.get.and.returnValue(of(MOCK_DATA)); // 订阅返回的Observable触发内部逻辑执行 component.dataFilter('').subscribe(filteredData => { expect(getApiSpy.get).toHaveBeenCalled(); // 空字符串应该返回全部原始数据 expect(filteredData.length).toBe(MOCK_DATA.length); expect(filteredData).toEqual(MOCK_DATA); done(); // 通知Jasmine异步测试完成 }); }); it('should return filtered data match the input value', (done) => { getApiSpy.get.and.returnValue(of(MOCK_DATA)); // 测试过滤包含ap的项 component.dataFilter('ap').subscribe(filteredData => { expect(getApiSpy.get).toHaveBeenCalled(); // 预期返回Apple、Apricot两个匹配项 expect(filteredData.length).toBe(2); expect(filteredData.map(item => item.foo)).toEqual(['Apple', 'Apricot']); done(); }); });
方式2:Angular fakeAsync + tick(同步写法更简洁)
import { fakeAsync, tick } from '@angular/core/testing'; it('should return filtered data match the input value', fakeAsync(() => { getApiSpy.get.and.returnValue(of(MOCK_DATA)); let filteredResult: any[] = []; component.dataFilter('ap').subscribe(res => filteredResult = res); tick(); // 触发所有微任务执行 expect(filteredResult.length).toBe(2); expect(filteredResult.map(item => item.foo)).toEqual(['Apple', 'Apricot']); }));
方式3:RxJS 7+ async/await写法
借助firstValueFrom/lastValueFrom可以用async/await语法简化异步逻辑:
import { firstValueFrom } from 'rxjs'; it('should return filtered data match the input value', async () => { getApiSpy.get.and.returnValue(of(MOCK_DATA)); const filteredResult = await firstValueFrom(component.dataFilter('ap')); expect(filteredResult.length).toBe(2); expect(filteredResult.map(item => item.foo)).toEqual(['Apple', 'Apricot']); });
内容的提问来源于stack exchange,提问作者YorkshireDevOliver
相关产品推荐
相关产品推荐

