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);
});
});
hostFixture.componentInstance
のmodel
値を変更しても、実際にはchildFixture.componentInstance
のdata
入力値は変更されません。これが、子コンポーネントのインスタンスが2つあることを認識した方法です。
私の質問は簡単です。どのようにしてchildFixture
を取得して、現在ある別のインスタンスではなく、HostComponent
テンプレートにあるコンポーネントフィクスチャを参照できますか?
ドキュメント 役に立たなかった。
ガイド で説明されているように、ホストコンポーネントインスタンスはTestBed.createComponent
、および子コンポーネントのインスタンスは、 debugElement
helper でBy
から選択できます。
childDebugElement = hostFixture.debugElement.query(By.directive(ChildComponent));
または:
childDebugElement = hostFixture.debugElement.query(By.css('child'));
上記の答えは良いです、本文の質問に答えますが、質問のヘッダー/タイトルは何か他のものを尋ねます。ヘッダーによって提起された質問にも答えたいと思いました。 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.
}
テストケースでこれを使用することもできますが、実際にテストしようとしている子コンポーネントを見つけるために使用します。
残りは、コメントで提起された議論の余地のある側面を満たすことです。
可能であれば、物事をプライベートにするという強力なケースもあります。あなたがそれを単体テストしたい場合、私はそれについてどう思うかわかりません。プライベートメンバーをテストする場合は、キャストする対象を明確にするために、キャストしてかっこで囲むことにより、プライベートメンバーを持つオブジェクトがパブリックにアクセスできるようにするTypeScriptコンパイラーを許可する必要があります。
コンポーネント内:
...
@ViewChild('child') private child;
...
テストでは:
...
(<any>component).child.value
(<any>component).child.method
...
DebugElement(s)のchildNodesを反復処理し、コンテキストプロパティにアクセスして、コンポーネントとそのプロパティにアクセスします。
let debugElement = hostFixture.debugElement.childNodes[x] as DebugElement
debugElement = debugElement.childNodes[x] as DebugElement
...
let component = debugElement.context as YourComponent
新しい子が追加された場合、間違ったchildNodeにアクセスする可能性があるため、これは非常に静的なアプローチです。 childNodesを通過して正しい名前を見つけるヘルパーメソッドを記述する方が適切です。