I am trying to write unit tests for an Angular component which can hide/show some contents passed as input to the component itself. The inputs expected are defined as TemplateRef.
my-component.component.ts
@Component({
selector: "my-component",
templateUrl: "./my-component.component.html",
styleUrls: ["./my-component.component.scss"],
exportAs: "mycomponent"
})
export class MyComponent {
private _expanded = false;
@Input()
set expanded(value: boolean) {
this._expanded = value;
}
@Input()
body: TemplateRef<any>;
@Input()
handler: TemplateRef<any>;
constructor() {}
toggleView() {
this.expanded = !this._expanded;
}
}
my-component.component.html
<div class="wrap">
<!-- Header -->
<main #header>
<header (click)="toggleAccordion()">
<div class="handler">
<ng-container [ngTemplateOutlet]="handler">
</ng-container>
</div>
<i class="icon icon-expand" [ngClass]="{ 'icon-expand': _expanded, 'icon-collapse': !_expanded }"></i>
</header>
</main>
<!-- Body -->
<div class="body" *ngIf="_expanded">
<ng-container [ngTemplateOutlet]="body"></ng-container>
</div>
</div>
What I want to test if the content passed through the input "body" is visible or not, but I can't figure it out how to instantiate in jasmine a "my-component" with a TemplateRef input.
The Angular documentation explains how to pass an input on the unit test script, but since I can't instantiate any TemplateRef object because TemplateRef is an abstract class, I don't know how to manage this.
my-component.component.spec.ts
...
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
component.body = /* What should I put here? */;
fixture.detectChanges();
});
....
I'll try to give you a demo code which you can extend further
Basically, you need to test this in a different way. Since you can't create your component without using TemplateRef
of another component, so you need to create a wrapper component and test your component by writing test case for WrapperComponent
@Component({
template: `
<ng-template #div1>Something here</ng-template>
<ng-template #div2>Many things here</ng-template>
<my-component [expanded]="expandedVal" [body]="div1" [handler]="div2"> </my-component>
`,
})
class WrapperComponent {
@ViewChild(MyComponent, { static: true }) appComponentRef: MyComponent;
public expandedVal = true;
}
describe('MyComponent', () => {
let app: MyComponent;
let fixture: ComponentFixture<WrapperComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WrapperComponent, MyComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WrapperComponent);
const wrapperComponent = fixture.debugElement.componentInstance;
app = wrapperComponent.appComponentRef; // this is where you get "MyComponent" component for testing
fixture.detectChanges();
});
it('should create the app', async(() => {
expect(app).toBeDefined();
}));
});
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