2015-09-19 50 views
0

我無法嘲笑和測試我的角度應用程序。鑑於下面的文件,我總是得到錯誤延期未定義。

我該如何正確地使用Promise模擬API?以及如何測試API確實正在運行並附加響應到$ scope.data變量?

控制器

angular.module('app').controller('controllerOne', [ 
    '$scope', 
    'API', 
    function($scope, API) { 
     $scope.init = function() { 
      $scope.data = API.query(function(response) { 
       return response; 
      }); 
     }; 

    } 
]); 

API服務

angular.module('app').factory('API', ['$resource', 
    function($resource) { 
     return $resource('api/url/:Id', { 
      Id: '@_id' 
     }, { 
      update: { 
       method: 'PUT' 
      } 
     }); 
    } 
]); 

控制器規格

describe('app Module', function() { 
    beforeEach(function() { 
     module('app'); 
    }); 
    var mockAPI, q, $scope, ctrl; 
    beforeEach(function() { 
     mockAPI = { 
      query: function() { 
       var deferred = q.defer(); 
       return deferred.promise; 
      } 
     }; 
    }); 
    beforeEach(inject(function($controller, $rootScope, $q) { 
     $scope = $rootScope.$new(); 
     q = $q; 
     ctrl = $controller('controllerOne', { 
      $scope: $scope, 
      API: mockAPI 
     }); 
    })); 
    it('should query API', function() { 
     spyOn(mockAPI, 'query').and.callThrough(); 
     $scope.init(); 
     deferred.resolve(); 
     $scope.$root.$digest(); 
     expect(mockAPI.query).toHaveBeenCalled(); 
    }); 
}); 

如果我運行下面的代碼,一切正常,,但我認爲這是不正確的,因爲我自己初始化API。

it('should query API', function() { 
    mockAPI.query(); 
    expect(mockAPI.query).toHaveBeenCalled(); 
}); 

什麼是和正確的方式做到這一點?

回答

0

您遇到的問題是由於mockAPI查詢中定義的延遲變量的範圍所致。它應該在套件級別進行限定,以便可以在您的測試中進行解析。

假設您的其他代碼是好的,以下內容將解決您的問題延遲未定義

describe('app Module', function() { 
    beforeEach(function() { 
     module('app'); 
    }); 
    var mockAPI, deferred, q, $scope, ctrl; 
    beforeEach(function() { 
     mockAPI = { 
      query: function() { 
       deferred = q.defer(); 
       return deferred.promise; 
      } 
     }; 
    }); 
    beforeEach(inject(function($controller, $rootScope, $q) { 
     $scope = $rootScope.$new(); 
     q = $q; 
     ctrl = $controller('controllerOne', { 
      $scope: $scope, 
      API: mockAPI 
     }); 
    })); 
    it('should query API', function() { 
     spyOn(mockAPI, 'query').and.callThrough(); 
     $scope.init(); 
     deferred.resolve(); 
     $scope.$root.$digest(); 
     expect(mockAPI.query).toHaveBeenCalled(); 
    }); 
});