2015-09-11 95 views
1

我花了數小時試圖弄清楚這一點。我試圖在Typescript中測試我的Angular控制器(在typeScript中寫入)和測試。我被卡在嘲笑服務到我的控制器。下面是代碼:TypeScript Angular Jasmine + Karma test

控制器:

export class ProductsController {  
    static $inject = ["ProductService", "$scope"]; 
    constructor(productsServices: AngularTest.Interfaces.IProductsService, $scope: any) { 


      productsServices.getAllProducts().then((response: ng.IHttpPromiseCallbackArg<AngularTest.Interfaces.IProducts[]>): any => { 
      $scope.currentPage = 1; 
      $scope.allProducts = <AngularTest.Interfaces.IProducts[]> response.data 

        $scope.cartItems = []; 
        $scope.modalAlerts = []; 

        $scope.maxItems = 3; 
        $scope.totalItems = $scope.allProducts.length; 

        $scope.itemsOnPage = $scope.allProducts.slice(0, $scope.maxItems); 
     }); 

     $scope.pageChanged = function() { 
      $scope.itemsOnPage = $scope.allProducts.slice(($scope.currentPage - 1) * $scope.maxItems, $scope.currentPage * $scope.maxItems); 
     }; 
    } 
} 

服務:

module AngularTest.Services{ 
    class ProductServices implements AngularTest.Interfaces.IProductsService{ 
     httpService: ng.IHttpService 

     static $inject = ["$http"]; 
     constructor($http: ng.IHttpService) 
     { 
      this.httpService = $http; 

     } 

     getAllProducts(): ng.IPromise<AngularTest.Interfaces.IProducts[]> { 
      return this.httpService.get('/api/Angular'); 
      }; 
    } 

    factory.$inject = ['$http']; 
    function factory($http : ng.IHttpService) { 
     return new ProductServices($http); 
    } 

    angular 
     .module('app.AngularTS') 
     .factory('ProductService', factory); 

} 

測試:

describe("TestService",() => { 

    var mock: ng.IMockStatic; 
    var $httpBackend: ng.IHttpBackendService; 
    var service; //AngularTest.Interfaces.IProductsService; 
    var rootScopeFake; 
    var controller; 
    var $controller: ng.IControllerService; 

    mock = angular.mock; 
    beforeEach(mock.module('app.AngularTS')); 

    beforeEach(() => inject(function (_$httpBackend_, $injector, $rootScope, _$controller_) { 
     $httpBackend = _$httpBackend_; 
     rootScopeFake = $rootScope.$new(); 
     service = $injector.get('ProductService');  
     $controller = _$controller_; 
    })); 

    afterEach(function() { 
     $httpBackend.verifyNoOutstandingExpectation(); 
     $httpBackend.verifyNoOutstandingRequest(); 
    }); 

    it("Should Call API", function() { 
     controller = $controller('ProductsController', { ProductService: service, $scope: rootScopeFake}); 

     spyOn(service, "getAllProducts"); 

     expect($httpBackend.expectGET('/api/Angular').respond([ 
      { "x": "xx", "xxx": "xxxx", "xxxxx": 5 }, 
      { "x": "xx", "xxx": "xxxx", "xxxxx": 5.5 }, 
      { "x": "xx", "xxx": "xxxx", "xxxxx": 6 }, 
      { "x": "xx", "xxx": "xxxx", "xxxxx": 0 } 
     ])).toHaveBeenCalled; 

     expect(service.getAllProducts).toHaveBeenCalled(); // this fails why ? 
     $httpBackend.flush(); 

    }); 
}); 

我不知道這是爲什麼不工作我recive。預期的間諜getAllProducts被調用。

回答

1

您應該在使用您正在窺視的方法之前創建您的間諜。由於該方法在控制器構造函數中使用。在啓動控制器之前應該創建間諜。

it("Should Call API", function() {   
    spyOn(service, "getAllProducts").and.callFake(function(){ 
     //return promise 
    }); 

    controller = $controller('ProductsController', { ProductService: service, $scope: rootScopeFake}); 

    .... 
+0

我已經這樣做了。現在我正在收回錯誤:TypeError:'undefined'不是一個對象(在ProductsController上評估'productsServices.getAllProducts()。') 。任何想法 ? –

+0

它期望getAllProducts返回一個承諾。你可以通過給你的間諜添加'and.callFake'來實現這一點。 (我編輯了我的代碼)我不是TypeScript的專家,因此我不確定如何使用ng.ipromise返回承諾。我把它留給你。 :-) – Koen

+0

仍然收回錯誤:TypeError:'undefined'不是一個對象(評估'spyOn(service,「getAllProducts」).callFake')方法:spyOn(service,「getAllProducts」)。和.callFake(( )=> { var deffered; deffered = q.defer(); deffered.resolve('xxxx'); return deffered.promise; }); –

相關問題