How can I mock a ControlContainer
instance so that I can test my component?
I have a child component that injects a ControlContainer
into the constructor, so its usage is
<acr-score-card formGroupName="score"></acr-score-card>
and the component itself is
@Component({
selector: 'acr-score-card',
templateUrl: './score-card.component.html',
styleUrls: ['./score-card.component.scss']
})
export class ScoreCardComponent implements OnInit {
...
form: FormGroup;
constructor(private ngControl: ControlContainer) { }
ngOnInit() {
this.form = <FormGroup>this.ngControl.control;
}
...
}
Everything works fine when I run in the browser but I cannot get the unit tests to work as I am not sure how to mock the ControlContainer
instance in order to setup the provider, this is the contents of my spec file:
describe('ScoreCardComponent', () => {
let component: ScoreCardComponent;
let fixture: ComponentFixture<ScoreCardComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [TestingModule],
declarations: [ScoreCardComponent],
providers: [/** what goes here to mock the ControlContainer */]
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ScoreCardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
So, to repeat the question, how can I mock a ControlContainer
instance so that I can test my component?
Thanks to @KiraAG for comment and was able to work out what was required from provided link, so posting answer here in case anyone else comes across this question
So in your test you need to provide
the ControlContainer
instance in your test module, this is basically going to be either a FormGroupDirective
or a FormControlDirective
depending on what you expect to be passed to your component.
For example, in your test file create the FormGroup
that represents the part of the form you are using
const fg: FormGroup = new FormGroup({
'answer': new FormControl(''),
...
});
Next create a FormGroupDirective
and set the form
property to the FormGroup
created above
const fgd: FormGroupDirective = new FormGroupDirective([], []);
fgd.form = fg;
Now in you test module setup you can provide the ControlContainer
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [TestingModule],
declarations: [ScoreCardComponent],
providers: [
{ provide: ControlContainer, useValue: fgd }
]
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
And that's it, the constructor injection is satisfied.
I used Neil Stevens's answer.
But I had
viewProviders: [{provide: ControlContainer, useExisting: FormGroupDirective}],
in the component.
So in tests I have to use
providers: [{provide: FormGroupDirective, useValue: fgd}],
Maybe this will help someone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With