0

私はコントローラにサービスの機能を呼び出す。以下は、今どのように(プロバイダとすることができる)サービスコールをモックを教えてくださいコードコントローラのジャスミンでのサービスの.successと.error

サービス

(function() { 
'use strict'; 
angular.module('MyApp') 
    .service('MyService', ['$http', function ($http) {             
     return { 
      getMyData: function (extension) {           
       return $http.get('www.something.com'); 
      }     
     }; 
    }]) 
})(); 

コントローラ

var getMyData = function() { 
      MyService.getMyData(extension).success(function (results) { 
       //Some functionality here 
      }) 
       .error(function (err, status) { 
       //Some functionality here 
      }); 
     } 
$scope.Call=function(){ 
    getMyData(); 
} 
$scope.Call(); 

です。完全なコードカバレッジで上記の関数をテストする方法。

マイspecファイル:

$provide.service("MyService", function() { 
      this.getMyData= function() { 
       var result = { 
        success: function (callback) { 
         return callback({ ServerFileName: "myserverfilename"}); 
        }, 
        error: function (callback) { 
         return callback({ ServerFileName: "myserverfilename" }); 
        } 
       }; 
       return result; 
}   

//...... 
my controller initiation and other code 

このコードは、エラーブロックをカバーし、

Cannot read property 'error' of undefined 

がどのように書くために/で私のサービスのgetMyData機能をモック私を助けてください、エラーを与えていません私の仕様ファイル

ありがとうございます。

答えて

0

あなたのサービスのためのモックを作成するspyonを使用する必要があります。テストファイルでこれを行う必要があります。

spyOn(MyService, "getMyData").and.callFake(() => { 
      return { 
       error: (callback) => { 
        return callback({}); 
       } 
      }; 
     }); 

.success.errorが古いと.then(successCallback, errorCallback)に置き換えられているので、私はあなたの質問

+0

このコードはどこでプロバイダまたは仕様書に記述しますか? – aditya

+0

あなたはそれぞれの前にこれを書かなければなりません。このようなもの:。 beforeEach(angular.mock.inject((MyServiceで)=> { するvar _myService = MyServiceで、 spyOn(_myService、 "getMyData")and.callFake(()=> { リターン{ エラー:(コールバック)=> { リターンコールバック({}); } }; }); } –

+0

IはbeforeEachでこれを行うと、それは「MyService.getMyData(...)エラーを示しています。成功は機能ではありません " – aditya

1

に答え希望、あなたはへの1回の呼び出しであなたのチェーン.success.error呼び出しを置き換えることを検討すべきである:以下のコードをご確認ください.thenメソッドに2つのコールバックを引数として渡します。最初は成功コールバック、もう1つはエラーコールバックです。

それはあなたが行うには喜んでいるものだ場合は、ここにあなたの作業例です:

あなたモジュール、サービスとコントローラ

angular.module('MyApp', []); 

angular.module('MyApp') 
.service('MyService', ['$http', function ($http) {             
    return { 
     getMyData: function (extension) {           
      return $http.get('www.something.com'); 
     }     
    }; 
}]); 

angular.module('MyApp') 
.controller('MyAppController', ['$scope', function($scope){ 
    var extension = { foo: 'bar' }; 
    var getMyData = function() { 
     MyService.getMyData(extension).then(function (results) { 
      //Some functionality here 
     }, function (err, status) { 
      //Some functionality here 
     }); 
    } 
    $scope.Call=function(){ 
     getMyData(); 
    } 
    $scope.Call(); 
}]); 

そして、あなたのテスト

describe('Controller: MyAppController', function(){ 
    beforeEach(module('MyApp')); 
    var flag, extension; 
    extension = { foo: "bar" }; 
    beforeEach(inject(function($controller, $rootScope, _MyService_) { 
     $scope = $rootScope.$new(); 
     MyService = _MyService_; 
     spyOn(MyService, 'getMyData').and.callFake(function(){ 
      return{ 
       then: function(successCallback, errorCallback){ 
        if(flag) successCallback(); 
        else errorCallback(); 
       } 
      } 
     }); 
     MyAppController = $controller('MyAppController', { 
      $scope: $scope, 
      MyService: MyService 
     }); 
    })); 

    describe('function: Call', function() { 
     //Text for Success Callback 
     it('should implicitly call MyService.getMyData with an extension object', function() { 
      flag = true; 
      $scope.Call(); 
      expect(MyService.getMyData).toHaveBeenCalledWith(extension); 
     }); 
     //Text for Error Callback 
     it('should implicitly call MyService.getMyData with an extension object', function() { 
      flag = false; 
      $scope.Call(); 
      expect(MyService.getMyData).toHaveBeenCalledWith(extension); 
     }); 
    }); 
}); 

更新: 私はこのようなものを仕事にしようとしましたが、運がありません。 .error()のコールは.success()コールにチェーンされており、それは.success()が呼び出された後にのみ呼び出されるもので、.error()のコールには決して到達せず、私たちは.error()をモックできません。あなたは報道でこの部分をスキップするコメント/*istanbul ignore next*/を使用し、または.then()に切り替えることができますので、どちらか

Cannot read property 'error' of undefined

:我々はそれをやってみてくださいもしそうなら、私たちはいつものようなエラーが発生します。

これが役に立ちます。

+0

あなたのソリューションに感謝します。成功をテストする方法がないということを意味しますか?それらに変更することなくエラーブロックを作成できますか?私はそれを使って書く方法を知っています。しかし、私たちはソースコードを変更することはできません。その他の方法で? – aditya

関連する問題