Angular组件@Input()属性测试返回null问题如何解决
问题排查与测试优化方案
核心错误点
- 选择器不匹配:子组件模板中
li标签的js-selector属性值为link--all(双中划线),测试代码中查询使用的是link-all(单中划线),无法匹配到元素因此返回null - 断言逻辑错误:
querySelector返回的是DOM元素对象,直接与linksMock数组做全等判断,逻辑完全不成立 - 实例初始化时机不合理:在
beforeEach阶段组件还未传入links值时就初始化了ChildTemplate,不符合用例隔离原则
优化后的测试代码
方案1:子组件单元测试(仅验证子组件输入渲染逻辑)
const linksMock: any[] = [1,2,3]; describe('ChildComponent', () => { let component: ChildComponent; let fixture: ComponentFixture<ChildComponent>; beforeEach( waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ChildComponent], imports: [RouterTestingModule], }).compileComponents(); fixture = TestBed.createComponent(ChildComponent); component = fixture.componentInstance; }) ); it('should create', () => { expect(component).toBeTruthy(); }); describe('When links are available', () => { it('Should render correct number of links', () => { // 给子组件传入模拟数据 component.links = linksMock; fixture.detectChanges(); // 用正确的选择器查询所有链接元素 const linkElements = fixture.nativeElement.querySelectorAll('[js-selector="link--all"]'); // 断言渲染的元素数量和传入数组长度一致 expect(linkElements.length).toBe(linksMock.length); }); }); });
方案2:父子组件集成测试(验证父到子的传值逻辑)
如果需要验证父组件传值到子组件的完整流程,需要把父组件也加入测试声明:
describe('Parent to Child Input Test', () => { let parentFixture: ComponentFixture<ParentComponent>; let parentComponent: ParentComponent; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ParentComponent, ChildComponent], imports: [RouterTestingModule] }).compileComponents(); parentFixture = TestBed.createComponent(ParentComponent); parentComponent = parentFixture.componentInstance; parentFixture.detectChanges(); })); it('should pass links correctly from parent to child', () => { // 触发父组件赋值逻辑 parentComponent.linkConformer(); parentFixture.detectChanges(); // 查询子组件实例,验证输入值 const childComponent = parentFixture.debugElement.query(By.directive(ChildComponent)).componentInstance; expect(childComponent.links).toEqual(['s','u','v']); // 也可以同时验证DOM渲染结果 const linkElements = parentFixture.nativeElement.querySelectorAll('[js-selector="link--all"]'); expect(linkElements.length).toBe(3); }); });
内容的提问来源于stack exchange,提问作者Enrique GF
相关产品推荐
相关产品推荐

