Angularユニットテストシリーズ-Jasmineを使用してAngularユニットテストを行う方法
6466 ワード
以下は私がユニットテストを書いていない人やほとんど書いていない人が準備したと仮定しているので、多くの概念的な問題を白話で説明し、Jasmineと対応する方法を組み合わせて説明します.
一、概念
toNotBe()等 toBeDefined()等 toBeUndefind()は に等しい. toBeNull()等 toBeTruthy()等 toBeFalsy()等 toBeLessThan()は に等しい toBeGreaterThan()は に等しい. toEqual()は に相当する. toNotEqual()は に相当する. toContain()は に相当する. toBeCloseTo()数値比較で精度を定義し、四捨五入してから比較します. toHaveBeenCalled()functionが呼び出されたかどうかを確認する toHaveBeenCalledWith()入力パラメータがパラメータとして呼び出されたかどうかを確認する . toMatch()等 toNotMatch()等 toThrow()functionがエラーを投げ出すかどうかをチェック これらのAPIは、以前は
これらのMatchersはほとんど私たちの日常的なニーズを満たすことができます.もちろん、独自のMatcherをカスタマイズして特別なニーズを実現することもできます.
幹将のテストコードは重要であるため、これらの繰り返しsetupとteardownコードを、それに対応する
上記の例と同様に、各
もちろん、各Specの実行週期間は、1つの空の
あるコンポーネントをテストすると、このコンポーネントは異なる状態で異なる結果を示すことがあります.この場合、
したがって、
需要はいつも三昧だが、せっかく書いたテストコードを削除するのか.いや...
SuitesおよびSpecsは、これらのテストコードブロックをスキップするために、それぞれ
三、Angularツールセットに合わせる
一、概念
Test Suite
テストキットは、単純なクラスでもいくつかのテスト例があるので、これらのテスト例を1つの分類にまとめてTest Suiteと呼びます.
Jasmineではdescribe
のグローバル関数を使用して表され、最初の文字列パラメータはSuiteの名前やタイトルを表すために使用され、2番目の方法パラメータはSuiteコードを実現することです.describe('test suite name', () => {
});
Specs
1つのSpecsは、テストの例に相当します.つまり、テストの特定のコード体を実装します.
Jasmineは、it
のグローバル関数を使用して表され、describe
と同様に、文字列と方法の2つのパラメータです.
各Specには、テストが必要なコードをテストするために複数のexpectationが含まれており、いずれかのexpectation結果がfalse
であれば、テスト例が失敗したことを示す.describe('demo test', () => {
const VALUE = true;
it('should be true', () => {
expect(VALUE).toBe(VALUE);
})
});
Expectations
expect
グローバル関数を使用して表現すると、テストを表す実際の値が1つしか受信されず、Matcherと所望の値を表す必要があると断言する.
二、常用方法
Matchers
照合操作を断言し、実際の値と期待値との比較を行い、結果をJasmineに通知すると、最終的にJasmineはこのSpecが成功したか失敗したかを判断します.
Jasmineは非常に豊富なAPIを提供し、いくつかのよく使われるMatchers:
describe('test suite name', () => {
});
describe('demo test', () => {
const VALUE = true;
it('should be true', () => {
expect(VALUE).toBe(VALUE);
})
});
Matchers
照合操作を断言し、実際の値と期待値との比較を行い、結果をJasmineに通知すると、最終的にJasmineはこのSpecが成功したか失敗したかを判断します.
Jasmineは非常に豊富なAPIを提供し、いくつかのよく使われるMatchers:
toBe()
同等===
!==
!== undefined
=== undefined
=== null
!!obj
!obj
<
>
==
!=
indexOf
new RegExp().test()
!new RegExp().test()
not
で負の値の判断を表していた.expect(true).not.toBe(false);
これらのMatchersはほとんど私たちの日常的なニーズを満たすことができます.もちろん、独自のMatcherをカスタマイズして特別なニーズを実現することもできます.
SetupとTeardown
幹将のテストコードは重要であるため、これらの繰り返しsetupとteardownコードを、それに対応する
beforeEach
とafterEach
のグローバル関数の中に置くことができます.beforeEach
は、各Specが実行される前、逆を表す.describe('demo test', () => {
let val: number = 0;
beforeEach(() => {
val = 1;
});
it('should be true', () => {
expect(val).toBe(1);
});
it('should be false', () => {
expect(val).not.toBe(0);
});
});
データ共有
上記の例と同様に、各
describe
の内部で共有できるように、各テストファイルの先頭、it
で対応する変数を定義することができる.もちろん、各Specの実行週期間は、1つの空の
this
オブジェクトを伴い、Specの実行が終了するまでクリアされ、this
を利用してデータ共有も可能である.ネストコード
あるコンポーネントをテストすると、このコンポーネントは異なる状態で異なる結果を示すことがあります.この場合、
describe
だけでは優雅に見えません.したがって、
describe
をネストすると、テストコード、テストレポートがよりきれいに見えます.describe('AppComponent', () => {
describe('Show User', () => {
it('should be show panel.', () => {});
it('should be show avatar.', () => {});
});
describe('Hidden User', () => {
it('should be hidden panel.', () => {});
});
});
テストコードブロックをスキップ
需要はいつも三昧だが、せっかく書いたテストコードを削除するのか.いや...
SuitesおよびSpecsは、これらのテストコードブロックをスキップするために、それぞれ
xdescribe
およびxit
のグローバル関数を使用することができる.三、Angularツールセットに合わせる
Spy
Angularのカスタムイベントはあまりにも一般的ですが、これらのカスタムイベントをテストするためには、イベントが正常に呼び出されているかどうかを監視することが重要です.幸いなことに、Spy
は関数が呼び出されるかどうかを監視するために使用することができます.これは私たちの良いパートナーです.
以下の例はしばらく気にしないで、しばらく体験してみましょう.describe('AppComponent', () => {
let fixture: ComponentFixture;
let context: TestComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestComponent]
});
fixture = TestBed.createComponent(TestComponent);
context = fixture.componentInstance;
// onSelected
spyOn(context, 'onSelected');
fixture.detectChanges();
});
it('should be called [selected] event.', () => {
// selected
//
expect(context.onSelected).toHaveBeenCalled();
});
});
非同期のサポート
まず、ここでの非同期とは、ObservableまたはPromiseを伴う非同期動作であるため、コンポーネントがサービスを呼び出してデータを非同期で取得するときのテストステータスである.
テスト対象のコンポーネントコードを仮定します.export class AppComponent {
constructor(private _user: UserService) {}
query() {
this._user.quer().subscribe(() => {});
}
}
async async
はパラメータと戻り値がなく、すべてのラップコードブロックのテストコードは、whenStable()
を呼び出すことで、処理される非同期動作をすべて完了させてからコールバックすることができる.最後に、断言操作を行います.it('should be get user list (async)', async(() => {
// call component.query();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(true).toBe(true);
});
}));
fakeAsync async
がブレークポイントに耐えられないようにコールバックする必要があるとすれば、fakeAsync
はこの点を解決することができます.it('should be get user list (async)', fakeAsync(() => {
// call component.query();
tick();
fixture.detectChanges();
expect(true).toBe(true);
}));
ここはコールバックをtick()
に変えただけで、どうですか.かっこいいですか.
Jasmineは非同期を持っています
前述したように非同期とは、ObservableやPromiseを伴う非同期行為を指しますが、setTimeout
に依存しているものや、外部購読結果が必要になってからトリガーされる場合はどうすればいいのでしょうか.done()
の方法を使用することができる.it('async demo', (done: () => void) => {
context.show().subscribe(res => {
expect(true).toBe(true);
done();
});
el.querySelected('xxx').click();
});
四、結論
この章のほとんどの内容はAngularユニットでよく使われるものをテストします.特に非同期部分では,3つの異なる非同期方式が共存するのではなく,具体的な業務に応じて採用する必要がある.そうでなければ、真TMの書き込みが難しいユニットテストが見つかります.結局これは非同期の世界です.
それ以来,Angular書き込みユニットテストの基礎を築いた.その後、このような基礎は説明されません.
それでは次の記事では、Component、Directive、PipeおよびServiceユニットテストをご紹介します.
happy coding!
describe('AppComponent', () => {
let fixture: ComponentFixture;
let context: TestComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestComponent]
});
fixture = TestBed.createComponent(TestComponent);
context = fixture.componentInstance;
// onSelected
spyOn(context, 'onSelected');
fixture.detectChanges();
});
it('should be called [selected] event.', () => {
// selected
//
expect(context.onSelected).toHaveBeenCalled();
});
});
export class AppComponent {
constructor(private _user: UserService) {}
query() {
this._user.quer().subscribe(() => {});
}
}
it('should be get user list (async)', async(() => {
// call component.query();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(true).toBe(true);
});
}));
it('should be get user list (async)', fakeAsync(() => {
// call component.query();
tick();
fixture.detectChanges();
expect(true).toBe(true);
}));
it('async demo', (done: () => void) => {
context.show().subscribe(res => {
expect(true).toBe(true);
done();
});
el.querySelected('xxx').click();
});
この章のほとんどの内容はAngularユニットでよく使われるものをテストします.特に非同期部分では,3つの異なる非同期方式が共存するのではなく,具体的な業務に応じて採用する必要がある.そうでなければ、真TMの書き込みが難しいユニットテストが見つかります.結局これは非同期の世界です.
それ以来,Angular書き込みユニットテストの基礎を築いた.その後、このような基礎は説明されません.
それでは次の記事では、Component、Directive、PipeおよびServiceユニットテストをご紹介します.
happy coding!