2016-04-05 22 views
1

APIデータを逆シリアル化するためにjsonapi-serializerライブラリを使用しています。私はangleの$ qコンストラクタを使ってコールバックを約束し、サービスでそれをラップしましたが、これはブラウザ上で正常に動作しますが、カルマ・ランナーのジャスミンを使ってテストすると、約束は解決しません。このサービス上のメソッド(私は活字体を使用しています注意してください)

public deserialize(type: string, data: any): any { 

// get the predefined options for resource type 
let deserializeOpts: any = this.deserializeOpts[type]; 

// use jsonapi-serializer 
// the options are not working 
let deserializer: any = new JAS.Deserializer({}); 

console.log(data); 
// return a promise with the parsed object 
return this._$q((resolve: any, reject: any) => { 
    deserializer.deserialize(data, (err: any, result: any) => { 
    if (result) { 
     console.log(resolve); 
     resolve(result); 
    } else { 
     console.log(err); 
     reject(err); 
    } 
    }); 
}); 
} 

これは

it('should flatten jsonapi user', function (done) { 
    var deserialized; 
    JsonapiParser.deserialize(type, apiUser).then(
    (result) => { 
     deserialized = result; 
     expect(deserialized).toEqual(apiUser); 
     done(); 
    } 
); 
}); 

それをデバッグしようと、しばらくして私のテストであるAnが、これは言及デシリアライザのサンプル使用ですサービス

// returns the promise so controller can display the errors 
return this.$http.get(url) 
    .then(
    (response: any) => { 
     if (response.data.data.length !== 0) {// deserialize data 
     return this._deserializer.deserialize('activities', response.data) // the deserializer service is called; 
     } else { // throw an error if data is empty 
     return this.$q.reject({ error: this.ACTIVITY.empty }); 
     } 
    }, 
    () => { 
     return this.$q.reject({ error: this.ACTIVITY.connectionError }); 
    } 
).then(
    (deserialized: any) => { // data is copied to original list so it doesn't lose it's bindings 
     angular.copy(deserialized, this.list); // the result from the deserializer is used 
     console.log(deserialized); 
     return this.list; 
    }); 

この最後のコードブロックは、コンパイル時に正常に動作し、ブラウザで実行されます。しかし、テストはタイムアウトになります。 deserializeメソッドの内部にログインすると、コールバックが解決されることがわかりますが、約束は決して消化されないようです。解決の呼び出しの後に$ rootScope。$ digest()を置くと、テストは機能しますが、特にコードがデプロイされたときに動作しているので、そこにハードコーディングする必要はありません。

答えて

2

あなたは$rootScope.$digest()に近づいていますが、アプリコードのダイジェストをトリガーする代わりに、$rootScope.$apply()でテストからトリガーしてください。

Testing PromisesおよびService Testingを参照してください。

+0

ダイジェストサイクルをトリガする適切な方法ですが、この場合は動作しません。$ qコンストラクタが動作する方法と関係があるかどうかわかりません。 – perezperret

+0

テストコード内から '。$ digest'の代わりに'。$ apply'を使ってダイジェストをトリガしてもテスト中の約束が解決されませんか?例えば ​​'deserialized = result; $ rootScope。$ apply(); .toEq(apiUser); ' –

+0

はい、私は' then'の中でログインしようとしましたが、呼び出されません。約束は、アプリケーションコード – perezperret

0

これは、私はそれを信じることができないブラウザ

で正常に動作します。あなたは決してresolveに電話していません!代わりにあなたがところで

console.log(result); 
resolve(result); 

を使用する必要が

console.log(resolve); 

の、典型的なnode-style callback promisificationif (err)、ないif (result)を使用しています。多分あなたはif (err || !result)が欲しいでしょう。

+0

あなたは絶対に正しいです、私はコールを外した"デバッグバージョン "をコピーしました解決するために、私はこれを反映するためにスニペットを編集しました、promisificationスタイリングのフィードバックに感謝します。 – perezperret

関連する問題