はじめに
AngularのUIコンポーネントの一つであるprimeNgをJestでユニットテストをするのに、Angular MaterialにあるHarnessesが欲しくなりました。
しかしprimeNgにはHarnessesにあたるものが存在しなくて、代替案を見つけたので共有します。
TL;DR
const debugEl = fixture.debugElement.query(By.directive(GrandchildComponent));
const grandchildComponentInstance: GrandchildComponent = debugEl.componentInstance;
GrandchildComponent.method();
対象コンポーネント
これをJestでテストします。
「はじめに」に記載の通り、primeNgを用います。
また、standaloneコンポーネントで行います。
HTML
<div>
<div>first = {{ first }}</div>
<div>rows = {{ rows }}</div>
<p-paginator
(onPageChange)="onPageChange($event)"
[first]="first"
[rows]="rows"
[totalRecords]="120"
></p-paginator>
</div>
TypeScript
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PaginatorModule, PaginatorState } from 'primeng/paginator';
@Component({
selector: 'app-target',
standalone: true,
imports: [CommonModule, PaginatorModule],
templateUrl: './target.component.html',
styleUrls: ['./target.component.scss']
})
export class AppTargetComponent {
first = 0;
rows = 10;
onPageChange(event: PaginatorState) {
this.first = event.first ?? this.first;
}
}
Jest
上記コンポーネントでページ遷移したときに走る onPageChange
がemitされたときの挙動をテストします。
test paginator
で確認します。
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Paginator } from 'primeng/paginator';
import { AppTargetComponent } from './target.component';
describe('AppTargetComponent', () => {
let component: AppTargetComponent;
let fixture: ComponentFixture<AppTargetComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [AppTargetComponent],
});
fixture = TestBed.createComponent(AppTargetComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('test paginator', () => {
const debugEl = fixture.debugElement.query(By.directive(Paginator));
const paginatorComponentInstance: Paginator = debugEl.componentInstance;
paginatorComponentInstance.onPageChange.emit({
page: 3,
first: 30,
rows: 10,
});
expect(component.first).toEqual(30);
});
});
まずは
fixture.debugElement.query(By.directive(Paginator));
で対象コンポーネントのDOMから p-paginator
を指定します。
p-paginator
は Paginator
と ドキュメント にありますので、その通り指定します。
ただこのままだと DebugElement
ですので、そのコンポーネントインスタンスを debugEl.componentInstance
で取得します。
これでAngularのViewChildに似た挙動を行えます。
あとはそのコンポーネントインスタンスから呼び出したいメソッド (ここではページネーションしたときの挙動をテストしたいのでOnPageChangeのemitされるメソッド)を呼び出します。
onPageChange(event: PaginatorState) {
this.first = event.first ?? this.first;
}
でfirstに値を更新していますので、 expect(component.first).toEqual(30)
で必要な値が入っているかを確認して完了です。
おわりに
簡単ではありますが、調べても見つからなかったので書きました。
終わります。