I have MainComponent
that uses ChildComponentA
as a @ViewChild
. MainComponent
is calling a method on ChildComponentA
.
I want to write an unit test case mocking ChildComponentA
. How can I do this using TestBed
(in Angular 2 RC5)?
Before I used to use overrideDirective(MainComponentName, ChildComponentA, MockChildComponentA);
Is there an equivalent to this using TestBed
?
I tried using
TestBed.overrideComponent(ChildComponentA,{
set: {
template: '<div></div>'
}
});
which just sets the template, but I want to mock the methods in the component as well.
I think in this case you can try and replace the child component with a mock component. Just create a mock component with the same selector and use TestBed to remove the declaration of the real child component and add the declaration to your mock component.
@Component({
selector: 'child',
template: '<div></div>'
})
class MockComponent {
}
And in your test do this to use the mock component:
TestBed.configureTestingModule({
imports: [MyModule],
declarations: [ParentComponent, MockComponent]
});
TestBed.overrideModule(MyModule, {
remove: {
declarations: [ParentComponent, ChildComponent],
exports: [ParentComponent, ChildComponent]
}
});
More details here: https://github.com/angular/angular/issues/10689.
Make sure to re-declare the ParentComponent, it does not work otherwise (not sure why).
If you use @ViewChild to get a reference to the child component, you will need to modify it to not use the type of the component, but an id. Use @ViewChild('child') instead of @ViewChild(ChildComponent). See second example from here: http://learnangular2.com/viewChild/
Notice that if the ChildComponent
is being declared in the TestModule itself, there is no need to override the module where the original was declared.
So, if your TestBed declaration looks like this:
TestBed.configureTestingModule({
declarations: [
ParentComponent,
ChildComponent // This is what you'd like to mock
]
});
Then, to override ChildComponent
all you need is:
@Component({
selector: 'child',
template: '<div></div>'
})
class MockChildComponent {
}
TestBed.configureTestingModule({
declarations: [
ParentComponent,
MockChildComponent // Notice the original is replaced by the mock
]
});
As long as ChildComponent
and MockChildComponent
have the same selector, this one should work.
The other answer given for this question works for the cases the ChildComponent
is being brought from a different module into the TestBed.
Note
If your ChildComponent
has any @Input
or @Output
, then include those too in your MockChildComponent
.