瞬间恒 發表於 2020-3-25 19:29:00

[Angular Unit Testing] Testing component with content projection

<p>Component to be tested:</p>
<div class="cnblogs_code">
<pre>&lt;ng-template #defaultPlaceholder&gt;<span style="color: rgba(0, 0, 0, 1)">
    Loading...
</span>&lt;/ng-template&gt;

&lt;div <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">loading-container</span><span style="color: rgba(128, 0, 0, 1)">"</span> *ngIf=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">loading$ | async</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;ng-<span style="color: rgba(0, 0, 0, 1)">container
      </span>*ngTemplateOutlet=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">outlet ? outlet : defaultPlaceholder</span><span style="color: rgba(128, 0, 0, 1)">"</span>
    &gt;&lt;/ng-container&gt;
&lt;/div&gt;</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">import {
    Component,
    OnInit,
    Input,
    TemplateRef,
    AfterViewInit
} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">@angular/core</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
import {LoadingService} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./loading.service</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
import {Observable} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">rxjs</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">

@Component({
    selector: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">loading</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    templateUrl: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./loading.component.html</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    styleUrls: [</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./loading.component.scss</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]
})
export </span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> LoadingComponent implements OnInit, AfterViewInit {
    loading$: Observable</span>&lt;boolean&gt;<span style="color: rgba(0, 0, 0, 1)">

    @Input() outlet: TemplateRef</span>&lt;any&gt;<span style="color: rgba(0, 0, 0, 1)">

    ngAfterViewInit() {}

    constructor(</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> loadingService: LoadingService) {}

    ngOnInit(): </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.loading$ = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.loadingService.loading$
    }

    </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> loadingContext() {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
            type: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">placeholder</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
      }
    }
}</span></pre>
</div>
<p>&nbsp;</p>
<p>Test code:</p>
<div class="cnblogs_code">
<pre>import {<span style="color: rgba(0, 0, 255, 1)">async</span>, ComponentFixture, TestBed} <span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">@angular/core/testing</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">

import {LoadingComponent} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./loading.component</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
import {LoadingService} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./loading.service</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">

import {ViewChild, Component, DebugElement} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">@angular/core</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
import {of} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">rxjs</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
import {By} </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">@angular/platform-browser</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="background-color: rgba(255, 255, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">

@Component({
    template: `
      </span>&lt;ng-template #loadingTmp&gt;&lt;p&gt;loading...&lt;/p&gt;&lt;/ng-template&gt;
      &lt;loading =<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">loadingTmp</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/loading&gt;<span style="color: rgba(0, 0, 0, 1)">
    `
})
</span><span style="color: rgba(0, 0, 255, 1)">class</span></span><span style="color: rgba(0, 0, 0, 1)"><span style="background-color: rgba(255, 255, 0, 1)"> WrapperComponent {
    @ViewChild(LoadingComponent) loadingComponentRef: LoadingComponent
}</span>

let loadingServiceSpy </span>=<span style="color: rgba(0, 0, 0, 1)"> {
    loading$: of(</span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">),
    </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> config() {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> {showContent: <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">}
    }
}

describe(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">LoadingComponent</span><span style="color: rgba(128, 0, 0, 1)">'</span>, () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    let component: LoadingComponent
    <span style="background-color: rgba(255, 255, 0, 1)">let wrapperComponent: WrapperComponent
    let fixture: ComponentFixture</span></span><span style="background-color: rgba(255, 255, 0, 1)">&lt;WrapperComponent&gt;</span><span style="color: rgba(0, 0, 0, 1)">
    let el: DebugElement

    beforeEach(</span><span style="color: rgba(0, 0, 255, 1)">async</span>(() =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      TestBed.configureTestingModule({
            declarations: [<span style="background-color: rgba(255, 255, 0, 1)">WrapperComponent</span>, LoadingComponent],
            providers: [{provide: LoadingService, useValue: loadingServiceSpy}]
      }).compileComponents()
    }))

    beforeEach(() </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      fixture </span>=<span style="color: rgba(0, 0, 0, 1)"> TestBed.createComponent(WrapperComponent)
      <span style="background-color: rgba(255, 255, 0, 1)">wrapperComponent </span></span><span style="background-color: rgba(255, 255, 0, 1)">=</span><span style="color: rgba(0, 0, 0, 1)"><span style="background-color: rgba(255, 255, 0, 1)"> fixture.debugElement.componentInstance</span>
      fixture.detectChanges()
      <span style="background-color: rgba(255, 255, 0, 1)">component </span></span><span style="background-color: rgba(255, 255, 0, 1)">=</span><span style="color: rgba(0, 0, 0, 1)"><span style="background-color: rgba(255, 255, 0, 1)"> wrapperComponent.loadingComponentRef</span>
      el </span>=<span style="color: rgba(0, 0, 0, 1)"> fixture.debugElement
      fixture.detectChanges()
    })

    it(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">should create</span><span style="color: rgba(128, 0, 0, 1)">'</span>, () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      expect(wrapperComponent).toBeDefined()
      expect(component).toBeDefined()
    })

    it(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">should use has p tag with text loading...</span><span style="color: rgba(128, 0, 0, 1)">'</span>, () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">const</span> p = el.queryAll(By.css(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">))
      expect(p.length).toBe(</span><span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
      expect(p[</span><span style="color: rgba(128, 0, 128, 1)">0</span>].nativeElement.textContent).toBe(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">loading...</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    })
})</span></pre>
</div>
<p>&nbsp;</p>
<p>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.</p><br><br>
来源:https://www.cnblogs.com/Answer1215/p/12568788.html
頁: [1]
查看完整版本: [Angular Unit Testing] Testing component with content projection