Angular单元测试:如何验证无关联子组件toggle方法被调用
错误原因
你当前测试报错的核心问题是 querySelector 的假实现返回了SidebarStubComponent类本身,而非类的实例,toggle()是类的实例方法,直接通过类调用自然会提示方法不存在。
另外你当前的桩写法也不符合实际运行逻辑:实际代码中document.querySelector返回的是挂载了toggle方法的自定义元素DOM实例,不是Angular组件类实例,不需要专门定义Angular桩组件。
正确单元测试写法
直接构造一个带toggle间谍方法的假DOM对象作为querySelector的返回值即可,代码如下:
it('should toggle sidebar action', async () => { // 构造带toggle方法的假侧边栏对象 const mockSidebar = { toggle: jasmine.createSpy('toggle') }; // 让querySelector匹配到#filter-sidebar时返回假对象 const querySpy = spyOn(document, 'querySelector').and.callFake((selector: string) => { return selector === '#filter-sidebar' ? mockSidebar : null; }); fixture.detectChanges(); await component.onSidebarButtonPressed(); // 断言querySelector被正确调用,且toggle方法被触发 expect(querySpy).toHaveBeenCalledWith('#filter-sidebar'); expect(mockSidebar.toggle).toHaveBeenCalled(); });
如果你的测试框架用的是Jest,把jasmine.createSpy替换成jest.fn()即可。
补充说明
你之前用@ViewChild拿不到实例是正常的,@ViewChild只能查询当前组件模板范围内的元素/组件实例,你的侧边栏组件和页面组件完全独立,不在同一个视图树内,自然无法通过@ViewChild获取。
内容的提问来源于stack exchange,提问作者Raajkumar
相关产品推荐
相关产品推荐

