2016-04-07 32 views
0

ジャスミンを使用して単体テストのテストケースを作成しました。私はサーバーから実際のデータをフェッチするコントローラでリソースベースのサービスをテストしようとしていますが、目的の結果が得られません。私が間違っているところに入力してください。以下、私が書かれているユニットテストである: は記述( 'NewStarterController'、関数(){ beforeEach(モジュール( 'て、myApp')); VaRの範囲、CTRL、$リソース;ジャスミンを使用した角度jsユニットテストコントローラのリソースベース工場用

 var context = 'http://localhost.com:8085/AngularPrototype/home'; 

     beforeEach(inject(function(_$resource_, $rootScope, $controller) { 
       $resource = _$resource_; 

       NewStarter = { 
        getNSData : function() { 
          return $resource(context + '/selfservice/newstarter/get', {}, { 
            get : { 
             method : 'GET' 
            } 
          }); 
        } 
       }; 
       scope = $rootScope.$new(); 

       $controller('NewStarterController', { 
        $scope : scope, 
        NewStarter : NewStarter 
       }); 

     })); 

     it('should test new starter data', function() { 

       NewStarter.getNSData().get({}).$promise.then(function(response) { 
        scope.refData = response; 
        scope.data(); 

       }); 


       expect(scope.data.length).toEqual(2); 

       expect(NewStarter.getNSData().get.length).toEqual(2); 

       expect(NewStarter.getNSData().get()).toEqual('formTitleNode'); 

     }); 

}); 



Below is the jasmine test result :: 

Jasmine 1.3.1 revision 1354556913finished in 0.183s 
• 
No try/catchFailing 1 spec1 spec | 1 failing 
NewStarterController 
should test new starter data 
NewStarterController should test new starter data. 
Expected 0 to equal 2. 
Expected 4 to equal 2. 
Expected { $promise : { $$state : { status : 0 } }, $resolved : false } to equal 'formTitleNode'. 





get.json  -> represents the data that is returned from server(Data returned from RestController) on hitting the url : http://localhost.com:8085/AngularPrototype/home/selfservice/newstarter/get 

SpecRunner.html-> is used to run the jasmine unit test. Below are the contents of this file : 
<!DOCTYPE html> 
<html> 

<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    <title>Jasmine Demo</title> 

    <script> 
     libraries here 
    </script> 
</head> 
<body> 
<!-- Include Angular and Angular Mocks--> 
<script>libraries here </script> 
    <!-- Include your source files here... --> 
<script src="services/services.js"></script> 
<script src="myApp.js"></script> 
<script src="controller/selfservice/NewStarterController.js"></script> 

<!-- Include your spec files here... --> 
<script src="jasmineunittest/NewStarterControllerTest.js"></script> 


<!-- Jasmine execution script (Standard Jasmine Bolierplate)--> 
<script type="text/javascript"> 
var jasmineEnv = jasmine.getEnv(); 
jasmineEnv.updateInterval = 1000; 
var htmlReporter = new jasmine.HtmlReporter(); 
jasmineEnv.addReporter(htmlReporter); 
jasmineEnv.execute(); 

</script> 

</body> 
</html> 


Below is the controller code (NewStarterController.js) which is unit tested : 

myApp.controller("NewStarterController", ['$scope','$modal', '$state', '$sce', 'NewStarter', function($scope,$modal, $state, $sce, NewStarter) { 


     $scope.data = function() { 
       NewStarter.getNSData().get({}, function(response) { 
        $scope.refData = response; 
        $scope.formTitle = []; 
        $scope.displayOptions = []; 
        angular.forEach($scope.refData.formTitleNode, function(contentItem) 
        { 
          var content = -1; 
          var title = -1; 
          angular.forEach(contentItem.fieldList, function(fieldBean) 
          { 
            if(fieldBean.fieldName == 'TITLE') 
            { 
             title = fieldBean.fieldValue; 

            } 
            if(fieldBean.fieldName == 'FORMATTEDCONTENTS') 
            { 
             content = fieldBean.fieldValue; 

            } 
          }) 
          $scope.formTitle.push({title:title, content:content}); 
        }) 

        angular.forEach($scope.refData.displayOptionsNode, function(contentItem) 
        { 

          var nsContent = -1; 
          var nsTitle = -1; 
          angular.forEach(contentItem.fieldList, function(fieldBean) 
          { 
            if(fieldBean.fieldName == 'TITLE') 
            { 
             nsTitle = fieldBean.fieldValue; 

            } 
            if(fieldBean.fieldName == 'FORMATTEDCONTENTS') 
            { 
             nsContent = fieldBean.fieldValue; 

            } 
          }) 
          $scope.displayOptions.push({nsTitle:nsTitle, nsContent:nsContent}); 
          $scope.selectedOption = ''; 
        }) 

        $scope.hasNewStarterSubmitted = $scope.refData.hasNewStarterSubmitted; 
        $scope.submittedSelectedOption = $scope.refData.submittedSelectedOption; 
        $scope.submittedStudentLoan = $scope.refData.submittedStudentLoan; 
        $scope.nsAlreadySubmittedValidationMsg = $scope.refData.nsAlreadySubmittedValidationMsg; 



        console.log('Success', response); 
       }, function(error) { 
        //alert(JSON.stringfy(error)) 
        $scope.contentLoadErrorMsg=error.data; 
        //console.error('ERR', error); 
       }); 
     } 
}]); 





Below is the code in services.js 

myApp.factory('NewStarter', function($resource, context) { 
     return { 
       getNSData: function() { 
        return $resource(context + '/selfservice/newstarter/get', {}, {get: {method:'GET'}}); 
       }, 
       submitNSForm: function() { 
        return $resource(context + '/selfservice/newstarter/submit', {}, {submit: {method:'POST'}}); 
       } 

     } 
}); 


Below is the code in myApp.js 

var myApp = angular.module('myApp', ['ngResource', 'ngSanitize', 'ui.bootstrap', 'ui.router']); 

myApp.constant('context', '/AngularPrototype/home'); 
myApp.constant('projectName', '/AngularPrototype'); 
myApp.config(function($stateProvider, $urlRouterProvider, projectName) { 
$urlRouterProvider.otherwise('/home'); 

$stateProvider .state('newStarter', { 
        url:'/newstarter', 
        templateUrl: projectName + '/newstarter', 
        controller: 'NewStarterController' 
       }) 
}); 


Thanks! 



Below i tried as per your suggestion but getting error while running the unit test: 
describe('NewStarterController', function() { 
beforeEach(module('myApp')); 
var scope, postDefer,NewStarter; 



     beforeEach(inject(function(_NewStarter_, $rootScope, $controller,$q) { 
       NewStarter = _NewStarter_; 
      postDefer = $q.defer(); 
      spyOn(NewStarter,'getNSData').and.returnValue(postDefer.promise); 
       scope = $rootScope.$new(); 

       $controller('NewStarterController', { 
        $scope : scope, 
        NewStarter : NewStarter 
       }); 

     })); 

     it('should test new starter data', function() { 

       NewStarter.getNSData().get({}); 
       postDefer.resolve(); 
       scope.$apply(); 

       expect(scope.data.length).toEqual(2); 

     }); 

}); 


Below are the errors while running the test : 

Error:[$injector:unpr] Unknown provider: NewStarterProvider <- NewStarter 
typeError: Unable to get property 'getNSData' of undefined or null reference 
+0

このplunkerをチェックしてください、あなたのモックgetNSDataは、$リソースを呼び出すだけではなく、約束を返し、あなたは結果を確認する必要が約束を解決する必要はありません。他の質問で私の答えをチェックしてください。http://stackoverflow.com/questions/36189329/testing-a-controller-that-execute-a-service-with-resource-response/36193211#36193211 – sdfacre

+0

私はあなたの提案に従って試しましたが、動作しませんでした。 getNSDataメソッドが認識されませんでした。コードを共有していただけますか?ありがとう! –

+0

私の提案どおりに試したコードで質問を更新できますか? – sdfacre

答えて

0

ことがあるので単体テストでは、単体テストのテストに集中する必要がありますが、できるだけ依存関係をすべて模倣しようとする必要があります。単価テストで実際の$リソースを使用することは望ましくありません。

- 1.コントローラで呼び出されるNewStarter.getNSData()などのサービスメソッドを呼び出す 2.偽のリソースobを返します。 3.偽リソースのメソッドをモックして(コントローラーで使用されているように)約束を返してください 4.成功ハンドラーをテストする約束を解決してください。

http://plnkr.co/edit/8l3mY1?p=preview

var mockResource = {get: function(){}}, $q; 
beforeEach(inject(function($rootScope, $controller, _$q_, NewStarter) { 
    $scope = $rootScope.$new(); 
    $q = _$q_; 
    spyOn(NewStarter, 'getNSData').and.callFake(function() { 
    return mockResource; 
    }); 

    ctrl = $controller('MainCtrl', { 
    $scope: $scope 
    }); 
})); 

it('should return value', function() { 
    var responseObj = {id: 1, name:'test'}; 
    spyOn(mockResource, 'get').and.callFake(function(data, func){ 
     var deferred = $q.defer(); 
     deferred.resolve(responseObj); 
     return deferred.promise.then(func); 
    }); 

    $scope.data(); 

    expect(mockResource.get).toHaveBeenCalled(); 
    $scope.$apply(); 

    expect($scope.refData).toEqual(responseObj); 
}); 
関連する問題