Component to be tested:
<ng-template #defaultPlaceholder> Loading... </ng-template> <div class="loading-container" *ngIf="loading$ | async"> <ng-container *ngTemplateOutlet="outlet ? outlet : defaultPlaceholder" ></ng-container> </div>
import { Component, OnInit, Input, TemplateRef, AfterViewInit } from '@angular/core' import {LoadingService} from './loading.service' import {Observable} from 'rxjs' @Component({ selector: 'loading', templateUrl: './loading.component.html', styleUrls: ['./loading.component.scss'] }) export class LoadingComponent implements OnInit, AfterViewInit { loading$: Observable<boolean> @Input() outlet: TemplateRef<any> ngAfterViewInit() {} constructor(private loadingService: LoadingService) {} ngOnInit(): void { this.loading$ = this.loadingService.loading$ } get loadingContext() { return { type: 'placeholder' } } }
Test code:
import {async, ComponentFixture, TestBed} from '@angular/core/testing' import {LoadingComponent} from './loading.component' import {LoadingService} from './loading.service' import {ViewChild, Component, DebugElement} from '@angular/core' import {of} from 'rxjs' import {By} from '@angular/platform-browser' @Component({ template: ` <ng-template #loadingTmp><p>loading...</p></ng-template> <loading [outlet]="loadingTmp"></loading> ` }) class WrapperComponent { @ViewChild(LoadingComponent) loadingComponentRef: LoadingComponent } let loadingServiceSpy = { loading$: of(true), get config() { return {showContent: false} } } describe('LoadingComponent', () => { let component: LoadingComponent let wrapperComponent: WrapperComponent let fixture: ComponentFixture<WrapperComponent> let el: DebugElement beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [WrapperComponent, LoadingComponent], providers: [{provide: LoadingService, useValue: loadingServiceSpy}] }).compileComponents() })) beforeEach(() => { fixture = TestBed.createComponent(WrapperComponent) wrapperComponent = fixture.debugElement.componentInstance fixture.detectChanges() component = wrapperComponent.loadingComponentRef el = fixture.debugElement fixture.detectChanges() }) it('should create', () => { expect(wrapperComponent).toBeDefined() expect(component).toBeDefined() }) it('should use has p tag with text loading...', () => { const p = el.queryAll(By.css('p')) expect(p.length).toBe(1) expect(p[0].nativeElement.textContent).toBe('loading...') }) })
Idea is to create a WrapperComponent to include our component. Then we are able to project content which need to be passed into the testing component.