使用Jasmine测试Angular中链式window方法的单元测试方案咨询
测试实现方案
你只需要提前构造好完整的链式mock对象结构即可,不需要处理复杂的嵌套spy逻辑,具体实现如下:
完整测试代码
describe('Service: gaming-header.service.ts', () => { let service: GamingHeaderService; let windowSpy: jasmine.SpyObj<Window>; let mockClassList: jasmine.SpyObj<DOMTokenList>; let mockHeader: { classList: jasmine.SpyObj<DOMTokenList> }; beforeEach(() => { // 1. 先mock classList的两个方法 mockClassList = jasmine.createSpyObj('DOMTokenList', ['contains', 'add']); // 2. 构造mock的header元素 mockHeader = { classList: mockClassList }; // 3. 构造完整的window mock对象,补全document.querySelector的实现 const mockWindow = jasmine.createSpyObj('Window', [], { document: jasmine.createSpyObj('Document', ['querySelector']) }); TestBed.configureTestingModule({ providers: [ GamingHeaderService, { provide: WINDOW, useValue: mockWindow }, ], }); service = TestBed.inject(GamingHeaderService); windowSpy = TestBed.inject(WINDOW) as jasmine.SpyObj<Window>; // 指定querySelector匹配'header'时返回我们的mockHeader windowSpy.document.querySelector.and.returnValue(mockHeader); }); // 测试用例1:header无games类时会添加 it('should add games class to header when class not exists', () => { // 模拟当前header没有games类 mockClassList.contains.withArgs('games').and.returnValue(false); service.addHeaderClass(); expect(mockClassList.add).toHaveBeenCalledOnceWith('games'); }); // 测试用例2:header已有games类时不重复添加 it('should not add games class to header when class already exists', () => { // 模拟当前header已有games类 mockClassList.contains.withArgs('games').and.returnValue(true); service.addHeaderClass(); expect(mockClassList.add).not.toHaveBeenCalled(); }); // 可选边界用例:不存在header元素时不会报错 it('should not throw error when header element not exists', () => { windowSpy.document.querySelector.withArgs('header').and.returnValue(null); expect(() => service.addHeaderClass()).not.toThrow(); }); });
原理解释
- Jasmine创建spy对象时,第三个参数可以传入要mock的对象属性,我们通过这个参数逐层补全
window.document的mock结构 - 提前把
classList的两个方法做成独立的spy对象,就可以直接监听方法的调用情况,不需要处理链式调用的spy嵌套 - 所有逻辑都在测试内存中完成,不需要操作真实DOM,测试运行效率更高,也不会受运行环境影响
内容的提问来源于stack exchange,提问作者user1809790
相关产品推荐
相关产品推荐

