[解決済み] AngularJS Jasmineのユニットテストで、プロミスを返すサービスをモックするにはどうすればよいですか?
2022-05-05 15:25:28
質問
私は
myService
を使用しています。
myOtherService
で、これはリモートコールを行い、promise を返します。
angular.module('app.myService', ['app.myOtherService'])
.factory('myService', [
myOtherService,
function(myOtherService) {
function makeRemoteCall() {
return myOtherService.makeRemoteCallReturningPromise();
}
return {
makeRemoteCall: makeRemoteCall
};
}
])
のユニットテストを作るには
myService
をモックする必要があります。
myOtherService
のような、その
makeRemoteCallReturningPromise
メソッドはプロミスを返します。これが私のやり方です。
describe('Testing remote call returning promise', function() {
var myService;
var myOtherServiceMock = {};
beforeEach(module('app.myService'));
// I have to inject mock when calling module(),
// and module() should come before any inject()
beforeEach(module(function ($provide) {
$provide.value('myOtherService', myOtherServiceMock);
}));
// However, in order to properly construct my mock
// I need $q, which can give me a promise
beforeEach(inject(function(_myService_, $q){
myService = _myService_;
myOtherServiceMock = {
makeRemoteCallReturningPromise: function() {
var deferred = $q.defer();
deferred.resolve('Remote call result');
return deferred.promise;
}
};
}
// Here the value of myOtherServiceMock is not
// updated, and it is still {}
it('can do remote call', inject(function() {
myService.makeRemoteCall() // Error: makeRemoteCall() is not defined on {}
.then(function() {
console.log('Success');
});
}));
上記からわかるように、私のモックの定義には
$q
を使って読み込まなければなりません。
inject()
. さらに、モックを注入するのは
module()
の前に来るはずです。
inject()
. しかし、一度変更したモックの値は更新されません。
どのようにすればよいのでしょうか?
どのように解決するのですか?
あなたのやり方がなぜうまくいかないのかわかりませんが、私は普段からこのように
spyOn
関数を使用します。こんな感じ。
describe('Testing remote call returning promise', function() {
var myService;
beforeEach(module('app.myService'));
beforeEach(inject( function(_myService_, myOtherService, $q){
myService = _myService_;
spyOn(myOtherService, "makeRemoteCallReturningPromise").and.callFake(function() {
var deferred = $q.defer();
deferred.resolve('Remote call result');
return deferred.promise;
});
}
it('can do remote call', inject(function() {
myService.makeRemoteCall()
.then(function() {
console.log('Success');
});
}));
また
$digest
を呼び出します。
then
関数が呼び出されます。を参照してください。
テスト
セクションの
$q ドキュメント
.
------edit------
あなたがやっていることをよく見てみると、あなたのコードに問題があることがわかったと思います。このコードでは
beforeEach
を設定する必要があります。
myOtherServiceMock
を全く新しいオブジェクトに変換します。その
$provide
はこの参照を見ることはありません。既存の参照を更新するだけでよいのです。
beforeEach(inject( function(_myService_, $q){
myService = _myService_;
myOtherServiceMock.makeRemoteCallReturningPromise = function() {
var deferred = $q.defer();
deferred.resolve('Remote call result');
return deferred.promise;
};
}
関連
-
JSクロスドメインソリューション リアクト構成 リバースプロキシ
-
Vueはランニングライト形式のテキストを水平方向にスクロールする機能を実装している
-
[解決済み】ローカルファイルを開くことができません - Chrome: ローカルリソースの読み込みが許可されていない
-
[解決済み】ExpressJS : res.redirect()が期待通りに動かない?
-
[解決済み】(Google Map API) Geocodeは以下の理由で成功しませんでした。REQUEST_DENIED
-
HTML5 LocalStorage ローカルストレージとセッションストレージの使用法
-
[解決済み] プライベートメソッド、フィールド、インナークラスを持つクラスをテストするにはどうすればよいですか?
-
[解決済み] Pythonの関数が例外を投げるかどうかをテストするにはどうすればよいですか?
-
[解決済み] Jasmineで'Error'が投げられることを期待するテストを書くには、どうすればよいですか?
-
[解決済み] AngularJS 。非同期データでサービスを初期化する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
JSクロスドメインソリューション リアクト構成 リバースプロキシ
-
vue for 登録ページ効果 vue for sms 認証コードログイン
-
Javascript Bootstrapのグリッドシステム、ナビゲーションバー、ローテーションの説明
-
vueディレクティブv-bindの使用と注意点
-
[解決済み】最大呼び出しスタックサイズ超過エラー
-
[解決済み】React - uncaught TypeError: 未定義のプロパティ 'setState' を読み取れない
-
[解決済み】Uncaught SyntaxError: JSONの位置0に予期しないトークンuがあります。
-
[解決済み】"フォームが接続されていないため、フォームの送信がキャンセルされました "というエラーの取得について
-
[解決済み】TypeErrorの解決方法。未定義またはヌルをオブジェクトに変換できない
-
[解決済み】エラー。Ionic使用中にモジュール '../lib/utils/unsupported.js' が見つかりませんでした。