如何在Angular中Mock内置slice pipe完成组件单元测试
Angular单元测试Mock内置SlicePipe解决方案
1. Mock SlicePipe 实现代码
Angular内置slice管道的逻辑完全对齐JavaScript数组的slice方法,你可以直接按以下逻辑实现Mock管道:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'slice' }) export class MockSlicePipe implements PipeTransform { transform(input: any[] | null | undefined, start: number, end?: number): any[] { // 处理空值边界 if (!Array.isArray(input)) return []; return input.slice(start, end); } }
之后将MockSlicePipe加入到TestBed的declarations配置中即可,同时不要忘记Mock你自定义的searchFilter管道。
2. 修复现有测试用例的逻辑错误
你的现有测试代码存在多个会导致报错的问题,需要同步修改:
- 接口返回值错误:你当前mock返回的是
of({})空对象,空对象没有length属性,会导致userCountLogs赋值为undefined - 断言逻辑错误:代码中
userCountLogs = data.length,说明userCountLogs本身是数字类型,你断言userCountLogs.length是非法操作,数字没有length属性 - 缺少
page默认值:模板中用到了(page-1) * pageSize,如果组件没有给page赋默认值1,会导致计算结果为NaN,触发slice管道参数错误 - 缺少异步等待逻辑:
fetchUserList是异步订阅逻辑,需要等待异步执行完成再做断言
修复后的测试用例参考:
import { fakeAsync, tick } from '@angular/core/testing'; import { of } from 'rxjs'; // ... 其他引入代码 describe('fetchUserList()',()=>{ it('should get list of users from notification service', fakeAsync(()=>{ component.pageOptions=[10,20,50,100]; component.page = 1; // 补充page默认值 // 修正返回值为数组类型 notificationServiceSpy.fetchUserList.and.returnValue(of([])) fixture.detectChanges(); // 触发ngOnInit执行 tick(); // 等待异步订阅回调执行完成 fixture.detectChanges(); expect(component.userList.length).toBe(0); expect(component.userList).toEqual(component.filteredUsers); expect(component.userCountLogs).toBe(0); // 直接断言数字的值,不需要取length expect(notificationServiceSpy.fetchUserList).toHaveBeenCalled(); })) })
内容的提问来源于stack exchange,提问作者Harkirat singh
相关产品推荐
相关产品推荐

