2016-12-07 52 views
3

私はすでにどこにでも見えましたが、私の特定のケースではまだ解決策を見つけることができませんでした。Angular 1.5 && Async/Await &&ジャスミンテスト

ユニットテストでは、角度1.5とカルマ/ジャスミン設定を使用しています。最初のソースコードでは、コントローラでES2017 async/awaitを使用しました。最後に手作業で$ digestの$ applyを追加していれば、それはうまくいくように思えました。 ですから、例えば:

async function loadData() { 
    try { 
    vm.isLoading = true; 
    vm.data = await DataService.getData(); 
    $scope.$apply(); 
    } 
    catch (ex) { 
    vm.isLoading = false; 
    } 
} 

この特定の機能のための自動テストを書くために、私はジャスミンのspyOnでDataService.getDataを嘲笑してみました。だから、私はこのようなものでした:スパイを追加

spyOn(DataService, 'getData').and.returnValue($q.when(fakeResult)); 

を働いたが、テストを実行するときに、コードがfakeResultで解決打たなく取得するようです。テスト自体に$ digest/$ applyを追加しようとしましたが、修正できませんでした。私も多くの研究をしましたが、まだ手がかりがありません。

誰かが手掛かりを持っていますか?

編集:$q約束と同じ方法をテストすることは正常に動作しますが、私は本当に非同期/のawaitを使用したいと思います...

+2

FYIの 'async/await'は、今年リリースされたES7ではなく、来年リリースされるES2017の一部です。 –

答えて

1

セットアップが類似している場合、私は知らないが、私たちの環境の中で、私が持っていましたjasmineテストで解決するために、非同期/待機の文を取得するためにいくつかのことを行う必要があります。

  • 私たちのテストでは、私は約束を返すサービスをモックアウトしようとしていました。私は$q.whenを返すことができないことが分かった。代わりに、実際のA +標準の約束を返さなければなりませんでした。私の推測では、Angularの$ qの約束は完全に標準に訴えるものではなく、代用品としては機能しないと考えています。

  • 私たちのテストではPhantomJSを使用しているため、これらのPromisesを取得するためにポリフィルを追加する必要がありました。

  • 私のテストで何度も、setTimeoutブロックにexpect文のいくつかをラップする必要がありました。再び、私の前提は、約束をするには追加の「ダニ」が必要だということです。

1

結果がない理由は、await以降は何も実行されないためです。反応成分の中にasync/awaitをテストしていたときも同様の問題がありました。 私は次のように、この試験方法であることをどこかで見つかった:

  1. あなたはhttps://www.npmjs.com/package/jasmine-async-suiteと同様のものを使用する必要があります - これは私が使用したものです。これは、あなたが約束を期待している非同期テストのためのものです。
    • また、約束が解決された後、待つことがないため、テストが停止するという別の問題もあります。それは非常に扱いにくいかもしれません。
  2. だから、あなたはあなたのケースDataService.getData()には、手動でメソッドを呼び出す必要があり、あなたはあなたのexpect文を置くことができる.then()メソッドを使用 - ので、このステップの、あなたのテストは約束を解決するのを待っています。

ここでは(私もテストでasync機能を使用しています)私のコードの例です。

it.async('should call `mySpecialMethod`', async() => { 
    const arrayToResolve = [ { data: 'data' } ]; 
    const SomeService = context.SomeService; 

    spyOn(props, 'mySpecialMethod'); 
    spyOn(SomeService, 'myMethodReturningPromise'); 
     .and.returnValue(Promise.resolve(arrayToResolve)); 

    //the method `myMethodReturningPromise` is called in componentDidMount 
    const wrapper = mount(<MyReactComponent {...props} />, context); 
    expect(SomeService.myMethodReturningPromise).toHaveBeenCalled(); 

    //now I am calling the method again 
    await SomeService.myMethodReturningPromise(); 

    //`mySpecialMethod` is calling after the `await` in my code 
    expect(props.mySpecialMethod).toHaveBeenCalled(); 
    //after that I am changing the state 
    expect(wrapper.state().arrayToResolve).toEqual(arrayToResolve); 
}); 

私はこれがあなたの役に立てば幸い:)

0

あなたはライブラリasync-await-jasmine使用することができます。

import * as angular from 'angular'; 
import 'angular-mocks'; 
import {yourModule} from "./your-module-path"; 
import {LoadDataService} from './load-data'; 
import {$it} from "async-await-jasmine"; 
import {IRootScopeService} from "angular"; 


describe('Calculator',() => { 
    let $httpBackend: angular.IHttpBackendService; 

    beforeEach(() => { 
    angular.mock.module(calculatorModule.name); 
    angular.mock.inject((_$httpBackend_) => { 
     $httpBackend = _$httpBackend_; 
    }); 
    }); 

    $it('should loadData', async() => { 
    $httpBackend.when('GET', '/loadData').respond('{"value": 5}'); 
    let sum = loadData(1, 4); 
    $httpBackend.flush(); 

    expect(await sum).toBe(10); 
    }); 
}); 
関連する問題