Angular 5测试:如何获取对子组件的引用

问题描述 投票:17回答:2

我正在尝试测试Angular应用程序中主机组件和子组件之间的交互。我不知道如何获取对父元素创建时创建的子组件的引用。这是设置:

child.component.spec.ts

@Component({template: `<child [data]="model"></child>`})
class HostComponent {
  public model:any;
}

describe('ChildComponent', () => {
  let hostFixture: ComponentFixture<HostComponent>;
  let childFixture: ComponentFixture<ChildComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ChildComponent, HostComponent]
    });
  }));

  beforeEach(() => {
    // this creates the child component as well, but how to get to it?
    hostFixture = TestBed.createComponent(HostComponent);

    // this creates a NEW instance of child component, not the one from the Host template
    // so it's not the instance I actually want to test
    childFixture = TestBed.createComponent(ChildComponent);
  });
});

改变model中的hostFixture.componentInstance值实际上并没有改变datachildFixture.componentInstance输入值;这就是我如何意识到有两个子组件实例。

我的问题很简单,我怎样才能让childFixture引用HostComponent模板中的组件夹具,而不是像我现在拥有的那样不同的实例?

The docs没有帮助。

angular unit-testing
2个回答
40
投票

the guide中所述,主机组件实例是使用TestBed.createComponent创建的,子组件实例可以使用debugElementBy helper中选择:

childDebugElement = hostFixture.debugElement.query(By.directive(ChildComponent));

要么:

childDebugElement = hostFixture.debugElement.query(By.css('child'));

4
投票

上面的答案很好,回答了正文的问题,但问题的标题/标题问了别的问题。我也想回答标题提出的问题。 Estus的答案对于特定用例是正确的,但Google会根据标题中的问题将您带到这里。

要使子组件不是本机元素:

测试组件(在问题中称为HostComponent):<child [data]="model" #child></child>

然后在类定义中:

@Component({template: `<child #child [data]="model"></child>`})
class HostComponent {
    public model:any;
    @ViewChild('child') child;
}

最后,在测试时,根据规范:

it('should do something', () => {
    component.child.value
    component.child.method
    // etc.
}

您可以在测试用例中使用它,我也可以找到您真正想要测试的子组件。


其余的是满足评论中提出的有争议的方面。

在可能的情况下,还有一个强有力的事情可以让事情变得私密。如果你想对它进行单元测试,我不确定我的感受。如果要测试私有成员,则必须通过将其作为公共可访问的类型脚本编译器公开访问,并将其包装在括号中以使其清楚显示您正在构建的内容。

在组件中:

...
    @ViewChild('child') private child;
...

在测试中:

...
    (<any>component).child.value
    (<any>component).child.method
...
© www.soinside.com 2019 - 2024. All rights reserved.