Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying a component defined in TestBed.overrideComponent

We are using

TestBed.overrideComponent(CoolComponent, {
    set: {
      template: '<div id="fake-component">i am the fake component</div>',
      selector: 'our-cool-component',
      inputs: [ 'model' ]
    }
  })

to override a component.

The component has a ViewChild which we configure in our ngOnInit method

@Component({
  selector: 'our-cool-component',
  templateUrl: 'cool.component.html'
})
export class CoolComponent implements OnInit, OnDestroy {
  @Input() model: SomeModel
  @ViewChild(CoolChildComponent) coolChildComponent;

  ngOnInit() {
    this.coolChildComponent.doStuff();
  }
}

The CoolComponent in turn lives in a Wrapper component.

When we call fixture.detectChanges() on the Wrapper fixture, this attempts to construct the CoolComponent, but it immediately dies when it calls doStuff() because CoolChildComponent is undefined.

Is there a way to get at the CoolComponent to stub its CoolChildComponent? It doesn't seem like we can get it off the Wrapper because it's only referenced through the template, not as a property of the component.

like image 255
Joe Taylor Avatar asked Sep 02 '16 16:09

Joe Taylor


People also ask

Should testbed override provider call before or after create component?

Another thing to note is that TestBed overrides need to happen before .createComponent is called. I tried the .overrideProvider call after .compileComponents and before .createComponent in the 2nd beforeEach, and it still worked fine.

What is the difference between the testbed injector and componentref injector?

The TestBed injector (acting like NgModule 's injector) and the component's injector. TestBed.get () uses the providers array in configureTestingModule while the componentRef.injector is using the component's injector which uses the component level providers, which is overrode by the set in overrideComponent.

Is there a testbed with overridex () method?

Although the inject example above does the trick, it adds a lot of cruft to the it declarations. Looking at the Angular docs, I found the TestBed has some .overrideX () methods ( .overrideModule, .overrideComponent, etc...).

How to create a mock component using testbed?

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.


1 Answers

ngOnInit() {
  this.coolChildComponent.doStuff();
}

should be

ngAfterViewInit() {
  this.coolChildComponent.doStuff();
}

because

View child is set before the ngAfterViewInit callback is called.

like image 98
Ankit Singh Avatar answered Oct 21 '22 18:10

Ankit Singh