ホームページ > ウェブフロントエンド > jsチュートリアル > Jasmine を使用した Angular 単体テストの概要

Jasmine を使用した Angular 単体テストの概要

青灯夜游
リリース: 2020-08-26 10:19:20
転載
2807 人が閲覧しました
<p>この記事では、Angular 単体テストに Jasmine を使用する方法について説明します。一定の参考値があるので、困っている友達が参考になれば幸いです。 </p> <p><img src="https://img.php.cn/upload/article/000/000/024/5f408f91953d2985.jpg" alt="Jasmine を使用した Angular 単体テストの概要" ></p> <p>以下は、単体テストをほとんどまたはまったく作成したことがない人が多くの概念的な問題を専門用語で説明でき、Jasmine も使用することを想定して私が作成したものです。それらに対応する方法について説明します。 </p> <p><span style="font-size: 20px;">#1. コンセプト<strong></strong></span></p> <p><span style="font-size: 18px;">テスト スイート<strong></strong></span></p>テスト スイート、単純なクラスにも複数のテスト ケースがあるため、これらのテスト ケースを 1 つのカテゴリに集めたものを <p>テスト スイート <strong> と呼びます。 </strong></p>Jasmine では、これは <p>describe<code> グローバル関数によって表されます。その最初の文字列パラメータはスイートの名前またはタイトルを表すために使用され、2 番目のメソッド パラメータはスイートを実装するために使用されます。コードです。 </code><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">describe(&#39;test suite name&#39;, () => { });</pre><div class="contentsignin">ログイン後にコピー</div></div></p><p><span style="font-size: 18px;">仕様<strong></strong></span></p>仕様は、テストのために実装するコードの特定の本体であるテスト ケースに相当します。 <p></p>Jasmine は、<p>describe<code> と同様に、</code>it<code> グローバル関数を使用して、文字列とメソッドの 2 つのパラメーターを使用してそれを表します。 </code></p>各仕様には、テストする必要があるコードをテストするための複数の期待値が含まれています。期待値の結果が <p>false<code> である限り、テスト ケースは失敗した状態であることを意味します。 </code><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">describe(&#39;demo test&#39;, () => { const VALUE = true; it(&#39;should be true&#39;, () => { expect(VALUE).toBe(VALUE); }) });</pre><div class="contentsignin">ログイン後にコピー</div></div></p><p><span style="font-size: 18px;">Expectations<strong></strong></span></p>アサーションは <p>expect<code> グローバル関数によって表され、テスト対象の代表 ## を 1 つだけ受け取ります #実際の値 </code> であり、<strong> 期待値 </strong> を表すために Matcher と照合する必要があります。 <strong></strong></p><p>2. 一般的なメソッド<span style="font-size: 20px;"><strong></strong></span></p><p>Matchers<span style="font-size: 18px;"><strong></strong></span>アサーション マッチング操作、実際の値と期待値を比較し、その結果を Jasmine に通知し、最後に Jasmine がこの仕様が成功するか失敗するかを判断します。 </p><p>Jasmine は非常に豊富な API を提供しており、一般的に使用されるいくつかの Matcher: </p><p></p><ul>toBe()<li> は <code>===</code>## と同等です。 <code>#toNotBe() は </code>!==</li><li><code>toBeDefined() と同等です </code>!== 未定義</li><li><code>toBeUnknown() </code>== = 未定義</li><li><code>toBeNull() は </code>=== null</li><li><code>toBeTruthy() と同等!!obj</code></li><li> toBeFalsy() は <code>!obj</code></li><li>toBeLessThan() は <code><</code></li># と同等です##toBeGreaterThan() は <li>><code>## と同等 </code>#toEqual() は </li>==<li><code></code>toNotEqual() は ## と同等#!=</li><li><code>toContain() は </code>indexOf</li><li><code>toBeCloseTo() と同等であり、数値を比較する際の精度を定義します。最初に四捨五入してから比較します。 </code></li>toHaveBeenCalled() 関数が呼び出されているかどうかを確認します <li><code>toHaveBeenCalledWith() 受信パラメータがパラメータとして呼び出されているかどうかを確認します </code></li>toMatch() は <li> と同等ですnew RegExp( ).test()</li><li></li>toNotMatch() は <li>!new RegExp().test()</li><li><code>toThrow() と同等かどうかを確認します。関数はエラーをスローします </code></li><li>これらの API は、以前は負の値の判定を示すために <code>not</code> を使用していました。 </li><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">expect(true).not.toBe(false);</pre><div class="contentsignin">ログイン後にコピー</div></div><li>これらの Matcher は、日常のニーズをほぼ満たすことができます。もちろん、特別なニーズに合わせて独自の Matcher をカスタマイズすることもできます。 </li></ul><p><code>セットアップとティアダウン</code></p><p></p>一般的なテスト コードは非常に重要なので、これらの繰り返しのセットアップ コードとティアダウン コードを対応する ## に置くことができます。 #beforeEach<p> と <span style="font-size: 18px;">afterEach<strong> はグローバル関数内にあります。 </strong></span></p>beforeEach<p> は、各仕様が実行される前を意味し、その逆も同様です。 <code><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">describe(&#39;demo test&#39;, () => { let val: number = 0; beforeEach(() => { val = 1; }); it(&#39;should be true&#39;, () => { expect(val).toBe(1); }); it(&#39;should be false&#39;, () => { expect(val).not.toBe(0); }); });</pre><div class="contentsignin">ログイン後にコピー</div></div></code><code></code>データ共有</p><p><code></code>上記の例のように、各テスト ファイルの先頭で定義できます (</p>describe#) ## 対応する変数。各 <p>it<span style="font-size: 18px;"> が内部で共有できるようにします。 <strong></strong> もちろん、各 Spec 実行サイクルには、Spec の実行が完了した後にクリアされるまで、空の </span>this</p> オブジェクトも伴います。<p>this<code> を使用することもできます。データ共有。 </code><code></code></p>ネストされたコード<p><code></code><code>コンポーネントをテストするとき、コンポーネントにはさまざまな状態が表示され、その結果、 # を 1 つだけ使用することがあります。 ##describe</code> では、現時点ではエレガントすぎるように思えます。 </p><p>したがって、<span style="font-size: 18px;">describe<strong> をネストすると、テストコードとテストレポートがより美しく見えます。 </strong><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">describe(&#39;AppComponent&#39;, () => { describe(&#39;Show User&#39;, () => { it(&#39;should be show panel.&#39;, () => {}); it(&#39;should be show avatar.&#39;, () => {}); }); describe(&#39;Hidden User&#39;, () => { it(&#39;should be hidden panel.&#39;, () => {}); }); });</pre><div class="contentsignin">ログイン後にコピー</div></div></span></p><p>テストコードブロックをスキップしてください<code></code></p><p>要求はいつも中途半端ですが、最終的に書かれたテストコードは削除する必要がありますか?いいえ...<code></code>スイートとスペックは、それぞれ </p>xdescribe<p> と <span style="font-size: 18px;">xit<strong> グローバル関数を使用して、これらのテスト コード ブロックをスキップできます。 </strong></span></p><p>3. Angular ツール セットとの連携</p><p><code></code><code></code>Spy</p><p><span style="font-size: 20px;"><p><a href="https://img.php.cn/upload/article/000/000/024/5f45c5bc2de7d900.jpg" target="_blank">Angular</a>的自定义事件实在太普遍了,但为了测试这些自定义事件,因此监控事件是否正常被调用是非常重要。好在,<code>Spy</code> 可以用于监测函数是否被调用,这简直就是我们的好伙伴。</p><p>以下示例暂时无须理会,暂且体验一下:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">describe(&#39;AppComponent&#39;, () => { let fixture: ComponentFixture<TestComponent>; let context: TestComponent; beforeEach(() => { TestBed.configureTestingModule({ declarations: [TestComponent] }); fixture = TestBed.createComponent(TestComponent); context = fixture.componentInstance; // 监听onSelected方法 spyOn(context, &#39;onSelected&#39;); fixture.detectChanges(); }); it(&#39;should be called [selected] event.&#39;, () => { // 触发selected操作 // 断言是否被调用过 expect(context.onSelected).toHaveBeenCalled(); }); });</pre><div class="contentsignin">ログイン後にコピー</div></div><p><span style="font-size: 18px;"><strong>异步支持</strong></span></p><p>首先,这里的异步是指带有 Observable 或 Promise 的异步行为,因此对于组件在调用某个 Service 来异步获取数据时的测试状态。</p><p>假设我们的待测试组件代码:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">export class AppComponent { constructor(private _user: UserService) {} query() { this._user.quer().subscribe(() => {}); } }</pre><div class="contentsignin">ログイン後にコピー</div></div><p><strong>async</strong></p><p><code>async</code> 无任何参数与返回值,所有包裹代码块里的测试代码,可以通过调用 <code>whenStable()</code> 让<strong>所有待处理异步行为都完成后</strong>再进行回调;最后,再进行断言操作。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">it(&#39;should be get user list (async)&#39;, async(() => { // call component.query(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(true).toBe(true); }); }));</pre><div class="contentsignin">ログイン後にコピー</div></div><p><strong>fakeAsync</strong></p><p>如果说 <code>async</code> 还需要回调才能进行断点让你受不了的话,那么 <code>fakeAsync</code> 可以解决这一点。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">it(&#39;should be get user list (async)&#39;, fakeAsync(() => { // call component.query(); tick(); fixture.detectChanges(); expect(true).toBe(true); }));</pre><div class="contentsignin">ログイン後にコピー</div></div><p>这里只是将回调换成 <code>tick()</code>,怎么样,是不是很酷。</p><p><strong>Jasmine自带异步</strong></p><p>如前面所说的异步是指带有 Observable 或 Promise 的异步行为,而有时候我们有些东西是依赖 <code>setTimeout</code> 或者可能是需要外部订阅结果以后才能触发时怎么办呢?</p><p>可以使用 <code>done()</code> 方法。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">it(&#39;async demo&#39;, (done: () => void) => { context.show().subscribe(res => { expect(true).toBe(true); done(); }); el.querySelected(&#39;xxx&#39;).click(); });</pre><div class="contentsignin">ログイン後にコピー</div></div></p> <p><span style="font-size: 20px;"><strong>四、结论</strong></span></p> <p>本章几乎所有的内容在Angular单元测试经常使用到的东西;特别是异步部分,三种不同异步方式并非共存的,而是需要根据具体业务而采用。否则,你会发现真TM难写单元测试。毕竟这是一个异步的世界。</p> <p>自此,我们算是为Angular写单元测试打下了基础。后续,将不会再对这类基础进行解释。</p> <p>happy coding!</p> <p>相关教程推荐:<a href="https://www.php.cn/course/list/20.html" target="_blank">angular教程</a></p>

以上がJasmine を使用した Angular 単体テストの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート