0

私はイオンアプリを書いた。私はそれにテストを追加し始めました。私は$resourcesの問題に直面しています。成功またはエラーで約束を処理する方法

.controller('newAccountCtrl', function($scope, $window, $rootScope, API, $ionicPopup, $state) { 
 
    $scope.newData = {}; 
 
    $scope.$on('$ionicView.enter', function() { 
 

 
    $scope.newData = {}; 
 
    }); 
 
    $scope.newInfo = function() { 
 
    API.newAccountInfo.update({ 
 
     restCode: $scope.newData.restore_code 
 
    }, $scope.newData, function(res, header) { 
 
     $scope.comty = 'update'; 
 
     $window.location.href = '#/login'; 
 
    }, function(err) { 
 
     if (err.data == null) 
 
     $rootScope.popup("Error", "no connection"); 
 
     else 
 
     $rootScope.popup('error', err.data.error); 
 
    }); 
 
    } 
 
})

とサービスで、私は機能で$resourcesを使用して要求を行います:

angular.module('starter.services', []) 
 
    .factory('API', function($rootScope, $resource, $ionicPopup, $ionicLoading, $window) { 
 
     return { 
 
     newAccountInfo: $resource(base + '/restoreinfo/:restCode', { 
 
      restCode: '@_restCode' 
 
     }, { 
 
      update: { 
 
      method: 'PUT' 
 
      } 
 
     }, { 
 
      stripTrailingSlashes: false 
 
     }); 
 
     }

と、このケースでは、私は、このコントローラーを持っています私のテストは、次のコード:

describe('newAccountCtrl', function() { 
 

 
    var controller, 
 
    deferredLogup, window, scope, 
 
    $rootScope, 
 
    $q, store, API, 
 
    PROMISE = { 
 
     resolve: true, 
 
     reject: false 
 
    }; 
 
    beforeEach(angular.mock.module('starter')); 
 
    beforeEach(module('starter.controllers')); 
 
    beforeEach(module('starter.services')); 
 
    beforeEach(module(function($provide, $urlRouterProvider) { 
 
    $provide.value('$ionicTemplateCache', function() {}); 
 
    $urlRouterProvider.deferIntercept(); 
 
    })); 
 

 
    beforeEach(inject(function($controller, _$rootScope_, $q, _API_, _$window_) { 
 
    $q = $q; 
 

 
    deferredLogup = $q.defer(); 
 
    $rootScope = _$rootScope_; 
 
    spyOn($rootScope, 'popup') 
 
    scope = $rootScope.$new(); 
 
    API = _API_; 
 
    window = _$window_; 
 

 
    spyOn(API.newAccountInfo, 'update').and.callThrough(function(callback) { 
 
     deferredLogup.promise.then(callback); 
 
     return deferredLogup.promise; 
 
    }); 
 

 
    controller = $controller('newAccountCtrl', { 
 
     '$scope': scope, 
 
     'API': API, 
 
     '$window': window 
 
    }); 
 

 
    })); 
 
    it('expect API.newAccountInfo to Have Been Called', function() { 
 
    scope.getloghist(); 
 
    expect(API.newAccountInfo.upadate).toHaveBeenCalled(); 
 
    }) 
 

 
    it('on success ', function() { 
 
    scope.newInfo(); 
 
    deferredLogup.resolve(); 
 
    scope.$digest(); 
 
    expect(scope.comty).toBeDefined(); 
 
    }); 
 

 
    it('on unsuccessful', function() { 
 
    scope.newInfo(); 
 
    deferredLogup.reject(); 
 
    scope.$digest() 
 
    expect($rootScope.popup).toHaveBeenCalled(); 
 
    }); 
 
});

最初のそれは渡す期待しますが、 "定義することが未定義の期待" というエラー

とリターン "成功時に" 第二1。

私はユニットテストを書くのが初めてです。私はここで何が欠けていますか?あなたのスパイで

答えて

0

spyOn(API.newAccountInfo, 'update').and.callThrough(function(callback){ 
    deferredLogup.promise.then(callback); 
    return deferredLogup.promise; 
}); 

.and.callThroughは機能のみを追跡します。それはそれを模倣しない(したがって、あなたが渡す関数は何もしていない)。ドキュメントから:and.callThroughでスパイを連結すること

、スパイはまだそれに対するすべての呼び出しを追跡しますが、それに加えて、実際の実装に委譲します。

「それはあなたが覗いている実際の機能を実行しています」というファンシーな話です。

あなたには、渡された機能を追跡して模倣する.and.callFakeが必要なようです。

編集間違っつ以上のものがありますようにそれが見えるので:

spyOn(API.newAccountInfo,'update').and.callFake(function(callback){ 
    deferredLogup.promise.then(callback); 
    return deferredLogup.promise; 
}); 

だから、あなたは、この無名関数をからかっている:

function(callback){ 
    deferredLogup.promise.then(callback); 
    return deferredLogup.promise; 
} 

この^機能は現在API.newAccountInfo.updateとして機能しています。この関数はの最初のパラメータをコールバックとして実行します。あなたがAPI.newAccountInfo.updateを実行しているところを見て行く

API.newAccountInfo.update({ 
    restCode: $scope.newData.restore_code 
}, $scope.newData, function(res, header) { 
    $scope.comty = 'update'; 
    $window.location.href = '#/login'; 
}, function(err) { 
    if (err.data == null) 
    $rootScope.popup("Error", "no connection"); 
    else 
    $rootScope.popup('error', err.data.error); 
}); 

//Simplifying this: 

API.newAccountInfo.update([Object], [Object], successCallback, errorCallback) 

あなたは第三第四パラメータではなく、最初の一つとして、コールバックを渡しています。しかし、あなたのモックはの最初のパラメータを実行しようとしています。だから、deferredLogup.promise.thenにオブジェクト(関数ではない)を供給しようとしています。

あなたのスパイは、次のようになります。

spyOn(API.newAccountInfo,'update').and.callFake(function(param1, param2, callback, errorCallback){ 
    deferredLogup.promise.then(callback); 
    return deferredLogup.promise; 
}); 

うまくいけば、助けること。

+0

私はcallTakeをcallFakeで置き換え、同じエラーが表示されます。** "定義されていないと予想される" **。 –

+0

私は私の答えを編集しました。それがあなたの問題を完全に解決するかどうかはわかりませんが、それはあなたをより近づけるはずです。 – jlogan

+0

その仕事に感謝します:-) –

関連する問題