単体テストで Angular OnInit ライフサイクルを再実行します
12441 ワード
問題
問題は、コンポーネントの初期化ライフサイクル、具体的には単体テストを作成する際の
OnInit
ライフサイクルを再実行できるようにすることです.ほとんどの場合、コンポーネントはいくつかの条件に基づいて異なる動作をします.
たとえば、ログイン ページまたはホームページを表示することを決定したいとします.そのため、ユーザーが既にログインしているかどうかを確認する必要があり、この確認は初期化中に行われる必要があります.
解決
コンポーネントをビルドするために
Angular CLI
を使用している場合、 ng generate component MyComponent
を使用し、ボイラープレート ユニット テストを使用してコンポーネントを生成します.単体テストファイルはこんな感じ
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MyComponent} from './my.component';
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
MyComponent
]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
ここで、
fixture.detectChanges()
は、コンポーネントで OnInit
をトリガーするメソッドです.これがわかったので、すでに解決策があります.
コンポーネントに
@input()
があるとします.これは、ユーザーの承認ステータスを示します.@Component({
selector: 'app-my-component',
template: `
<ng-container *ngIf="isLoggedIn else notLoggedInTemplate">
<app-home></app-home>
</ng-container>
<ng-template #notLoggedInTemplate>
<app-authorization></app-authorization>
</ng-template>
`
})
export class MyComponent implements OnInit {
@Input() isLoggedIn: boolean;
ngOnInit(): void {
if (this.isLoggedIn)
this.doSomethingBaseOnLogIn();
}
}
したがって、このコンポーネント スクリプトに基づいて、コンポーネントを 2 回 (単体テスト内で) 作成し、
isLoggedIn
フィールドに渡し、fixture.detectChanges()
を実行して、コンポーネントが期待どおりに動作するかどうかをテストできるようにする必要があります.単体テストは次のようになります
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
MyComponent,
AuthorizationComponent,
HomeComponent
]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('Behave correctly base on "isLoggedIn" status', () => {
it('should display login component if not logged in', () => {
fixture = TestBed.createComponent(SearchFormComponent);
component = fixture.componentInstance;
component.isLoggedIn = false;
fixture.detectChanges();
const myComponent = fixture.debugElement.nativeElement as HTMLElement;
expect(myComponent.querySelector('app-authorization')).toBeTruthy();
});
it('should display home component if already logged in', () => {
fixture = TestBed.createComponent(SearchFormComponent);
component = fixture.componentInstance;
component.isLoggedIn = true;
fixture.detectChanges();
const myComponent = fixture.debugElement.nativeElement as HTMLElement;
expect(myComponent.querySelector('app-home')).toBeTruthy();
});
});
});
これで、コンポーネントが初期化されるたびに条件を変更することで、渡された
input
に基づいてコンポーネントが期待どおりに動作することを確認できます.コメントで質問があればお気軽にお尋ねください.
Reference
この問題について(単体テストで Angular OnInit ライフサイクルを再実行します), 我々は、より多くの情報をここで見つけました https://dev.to/ussdlover/re-run-angular-oninit-lifecycle-in-unit-test-53h8テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol