2015-11-07 64 views
2

我想知道如何用params單元測試AngularJs $資源查詢。

我有這樣的:

services.js

angular.module('conciergeApp.services', ['ngResource']) 
    .factory('Reply', function($resource) { 
     return $resource('/api/reply/:id/'); 
    }); 

controllers.js

conciergeControllers.controller('ReplyCtrl', ['$scope', 'Reply', 
    function($scope, Reply) { 

     $scope.hotel_replies = Reply.query({ 
      hotel: $scope.hotel_id 
     }); 
    } 
]); 

所以,這被這裏查詢的API端點:

'/api/reply/?hotel=<hotel_id>' 

// aka 

'/api/reply/?hotel=1' 

這在手動測試時有效,但您如何對此進行單元測試?

With Jasmine spyOn$httpBackend。哪個會好?

這可以用嗎?用茉莉花2.0和htmlRunner

spyOn(object, 'method').andCallFake(function({foo:bar}) { 
    return myMockObject 
}); 
+0

這裏有幾個位給你的系統。你想要單元測試哪部分?你想檢查你的控制器是否在回覆服務上進行了正確的調用,或者你想檢查回覆服務是否按預期使用$ resource,或者你想檢查$資源是否有效? – davestevens

+0

@dst我想檢查'controller'是否使用指定的參數'?hotel__isnull = True'進行正確的調用,並且'$ resource'起作用。 –

+0

我不認爲你需要檢查$資源是否正在工作 - 它是一個從角度的外部依賴關係,你可以假設它是在發佈之前進行單元測試的。你可以專注於單元測試你自己的代碼。 – davestevens

回答

2

here:我嘗試這種模式,但不能這樣做成功。下面再說明:您ReplyCtrl單元測試裏面

所以:

describe('ReplyCtrl Controller', function() { 
    var Reply; 
    var ReplyCtrl; 
    var $scope; 
    var ReplyQueryMock; 
    var HOTEL_ID = 1234; 
    beforeEach(module('conciergeApp')); 
    beforeEach(inject(function (_Reply_, $controller, $rootScope) { 
     // This object can be used throughout your controller unit test for the 
     // response of calling the Reply.query method 
     ReplyQueryMock = {}; 
     Reply = _Reply_; 
     spyOn(Reply, 'query').and.returnValue(ReplyQueryMock); 
     $scope = $rootScope.$new(); 
     $scope.hotel_id = HOTEL_ID; 
     ReplyCtrl = $controller('ReplyCtrl', {$scope: $scope}); 
    })); 

    it('should populate hotel_replies', function() { 
     expect(Reply.query).toHaveBeenCalledWith({ 
      hotel: HOTEL_ID 
     }); 
     expect($scope.hotel_replies).toBe(ReplyQueryMock); 
    }); 
}); 

這將模擬出您的回覆服務,並返回一個嘲笑對象的查詢。您將驗證您的$ scope的hotel_replies是調用Reply.query和$ scope中存在的hotel_id的結果。

編輯:推測$資源已經由您(由Angular團隊!)進行單元測試。您可能只想驗證是否使用正確的URL設置資源,而不是深入瞭解$資源的內部實際情況(例如,調用$ http)。小提琴以上鍊接更新,並且看起來像以下:

describe('Reply Resource', function() { 
    var Reply; 
    var $resource; 
    var ReplyResourceMock; 
    beforeEach(module('conciergeApp.services', function ($provide) { 
     // Mock out $resource here 
     $provide.factory('$resource', function() { 
      ReplyResourceMock = {}; 
      var $resource = jasmine.createSpy('$resource'); 
      $resource.and.returnValue(ReplyResourceMock); 
      return $resource; 
     }); 
    })); 
    beforeEach(inject(function (_Reply_, _$resource_) { 
     Reply = _Reply_; 
     $resource = _$resource_; 
    })); 

    it('should initialize resource', function() { 
     expect($resource).toHaveBeenCalledWith('/api/reply/:id/'); 
     expect(Reply).toBe(ReplyResourceMock); 
    }); 
}); 

從原來的答案,可能是矯枉過正,因爲你使用$資源抽象$ HTTP(在小提琴仍然所示)

然後驗證$資源從您的回覆工廠/服務正常工作,您將需要注入$ httpBackend。您可以驗證是否使用正確的數據調用了正確的REST端點。