2014-02-13 34 views
5

我剛開始使用ng-table,我試圖通過茉莉花單元測試來測試它(不確定這是否是測試我的控制器的最佳方法),我不斷遇到這個錯誤;

TypeError: Cannot set property '$data' of null 
    at project/vendor/assets/javascripts/ng-table-0.3.1/ng-table.src.js:396:55 
    at C (project/vendor/assets/javascripts/angular-min.js:92:375) 
    at project/vendor/assets/javascripts/angular-min.js:94:28 
    at h.$eval (project/vendor/assets/javascripts/angular-min.js:102:308) 
    at h.$digest (project/vendor/assets/javascripts/angular-min.js:100:50) 
    at h.$apply (project/vendor/assets/javascripts/angular-min.js:103:100) 
    at f (project/vendor/assets/javascripts/angular-min.js:67:98) 
    at handleResponse (project/vendor/assets/javascripts/angular-mocks.js:1160:9) 
    at Function.$httpBackend.flush (project/vendor/assets/javascripts/angular-mocks.js:1491:26) 
    at null.<anonymous> (project/spec/javascripts/unit/debtors_controller_spec.js.js:50:24) 

這裏是我設置的ngTableParams在我的控制器

# Setup ng-table with defaults and data 
    $scope.tableParams = new ngTableParams({ 
    page: 1, 
    count: 10, 
    sorting: { code: 'asc'} 
    }, { 
    # data is created by ngTableParams 
    total: 0, 

    # ng-table will ask for updated data, this is where it gets it from. 
    getData: ($defer, params) -> 
     # Go get a list of debtors 
     Debtor.query {}, (data) -> 
     # Once successfully returned from the server with my data process it. 
     params.total(data.length) 

     # Filter 
     filteredData = (if params.filter then $filter('filter')(data, params.filter()) else data) 

     # Sort 
     orderedData = (if params.sorting then $filter('orderBy')(filteredData, params.orderBy()) else data) 

     # Paginate 
     $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count())) 
    }) 

這裏是茉莉測試

# ================================================================================ 
    # Delete tests 
    # ================================================================================ 
    describe "destroy", -> 
    beforeEach(inject (($controller, $rootScope, $location, $state, $httpBackend) -> 
     ctrl = $controller('DebtorsController', { 
     $scope: @scope, 
     $location: $location 
     }) 
    )) 

    it "gets new listing", -> 
     @scope.debtors = [{id: 1, name: "Good guys"}, {id: 2, name: "John"}] 
     @httpBackend.whenDELETE('/clients/1').respond(200) 
     @httpBackend.whenGET('/debtors').respond(200, [{name: "John"}]) 
     @scope.destroy(1) 
     @httpBackend.flush() 
     expect(@scope.debtors[0].name).toEqual('John') 

這裏是我的刪除代碼(工作)

# -------------------------------------------------------------------------------- 
    # Delete 
    # -------------------------------------------------------------------------------- 
    $scope.destroy = (id) -> 
    Client.delete 
     id: id 
    , (response) ->    # Success 
     flash("notice", "Client deleted", 2000) 
     $scope.tableParams.reload() # Reload ng-table data, which will get a new listing from the server. 
    , (response) ->    # Failure 

回答

6

你可以顯示代碼在您的控制器中初始化ngTableParams?

問題是ng-table使用ngTableController來設置$scopengTableParams。既然你是單元測試,你將不會有ngTableController,所以的ngTableParams將爲空。你應該在你的單元測試中手動設置$scopengTableParams。嘗試類似這樣的JS的東西(很討厭的CoffeeScript,所以轉換成你的需求):

beforeEach(inject(function ($controller, $rootScope) { 
      scope = $rootScope.$new(); 
      ctrl = $controller('DebtorsController', { 
       $scope: scope, 
       $location: $location 
      }); 
      scope.tableParams.settings().$scope = scope; 
     })); 

假設你有這樣的事情在你的控制下,你初始化你ngTableParams

$scope.tableParams = new ngTableParams({ 
    page: 1,   // show first page 
    count: 10   // count per page 
}, { 
    total: data.length, // length of data 
    getData: function($defer, params) { 
     $defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count())); 
    } 
}); 
+0

用Ctrl。 ngTableParams.settings()。$ scope = scope或ctrl.tableParams.settings()。$ scope = scope看起來不起作用,我得到的錯誤無法調用未定義的方法'settings' – map7

+0

@ map7根據第一行在我的回答中:「你可以在你的控制器中顯示你初始化ngTableParams的代碼嗎?」您需要引用您應該在控制器上公開的ngTableParams變量。例如,如果你在你的控制器中有''scope.tableParams = new ngTableParams(......)',那麼你的單元測試應該有'scope.tableParams.settings()。$ scope = scope;'See updated回答。 – Beyers

+0

我用我的控制器更新了我的問題。測試正在進一步進行。現在它正在抱怨預期線,而不是等同於'約翰'它仍然是'好人'和'約翰'。如果我通過瀏覽器手動測試它的工作。我應該檢查@ scope.debtors [0] .name還是應該檢查其他的最終結果? – map7