2013-07-02 38 views
19

Chúng tôi sử dụng nghiệp để kiểm tra các dịch vụ góc của chúng tôi, các dịch vụ này chứa $ http cuộc gọi, vì vậy chúng tôi có một $ httpbackend giả tại chỗ để chúng tôi có thể chạy các ứng dụng mà không cần máy chủ và db. hoạt động tốt, dịch vụ có thể gọi $ http ("someurl? Id = 1234") và chúng tôi lấy lại dữ liệu đúng.Angular 1.1.5 thử nghiệm dịch vụ dựa trên lời hứa

Nhưng khi chúng tôi cố gắng làm điều tương tự trong các thử nghiệm đơn vị, chúng tôi không thể có được nó để làm việc, lời hứa không bao giờ giải quyết, khi nó liên quan đến $ http

Các dịch vụ:

getAllowedTypes: function (contentId) { 
    var deferred = $q.defer(); 
    $http.get(getChildContentTypesUrl(contentId)) 
     .success(function (data, status, headers, config) { 
      deferred.resolve(data); 
     }). 
     error(function (data, status, headers, config) { 
      deferred.reject('Failed to retreive data for content id ' + contentId); 
     }); 
    return deferred.promise; 
} 

Các $ chế giễu httpbackend

$httpBackend 
    .whenGET(mocksUtills.urlRegex('/someurl')) 
    .respond(returnAllowedChildren); //returns a json object and httpstatus:200 

Bài kiểm tra

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 

    $rootScope.$digest(); 

    expect(collection.length).toBe(3); 
}); 

nhưng bộ sưu tập không được xác định, .then() không bao giờ được gọi.

cố gắng khá nhiều tất cả mọi thứ để có được những lời hứa để giải quyết, $ rootScope. $ Apply(), $ tiêu hóa, $ httpBacke.flush(), nhưng không làm việc

Vì vậy, chế giễu $ httpBackend hoạt động khi gọi từ bộ điều khiển trong ứng dụng, nhưng không phải khi các dịch vụ được gọi trực tiếp trong các thử nghiệm đơn vị nghiệp vụ

Trả lời

7

Bạn không cần phải tiêu hóa hai lần vì các cuộc gọi $ httpBackend.flush() tự tiêu hóa. Bạn phải thực hiện cuộc gọi, gọi thông báo để giải quyết yêu cầu chặn, cuộc gọi xả.

Đây là một Plnkr làm việc: http://plnkr.co/edit/FiYY1jT6dYrDhroRpFG1?p=preview

+1

Kees de Kooter đưa ra nhận xét trong một câu trả lời khác dưới đây rằng $ rootScope không bắt buộc. Tôi chia rẽ plunkr và nhận xét tất cả các tập quán $ rootScope. Bài kiểm tra vẫn trôi qua: http://plnkr.co/edit/4ladJi7TAQ4sFdzuGmDr?p=preview – chashi

4

Trong trường hợp của bạn, bạn phải $ digest hai lần, một lần cho $ httpBackend và một lần nữa cho riêng bạn hoãn lại.

Vì vậy:

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 
    $httpBackend.flush(); 
    $rootScope.$digest(); 

    expect(collection.length).toBe(3); 
}); 
+0

Cố gắng .flush() đã có, nhưng được: "Lỗi: Không yêu cầu đang chờ để tuôn ra!" đây có vẻ là lỗi phổ biến kể từ 1.1.4: https://github.com/angular/angular.js/issues/2431 –

+0

Thứ tự không đúng ở đây, bạn cần phải tiêu hóa $ trước khi bạn tuôn ra. – user553086

4

Bạn sắp hoàn tất. Trong trường hợp của bạn, bạn chỉ cần ép buộc một chu trình tiêu hóa trước khi xóa bỏ phần phụ trợ HTTP. Xem mã mẫu bên dưới.

it('should return a allowed content type collection given a document id', function(){ 

    var collection; 
    contentTypeResource.getAllowedTypes(1234).then(function(result){ 
     collection = result; 
    }); 

    $rootScope.$digest(); 
    $httpBackend.flush(); 
    expect(collection.length).toBe(3); 
}); 
+0

nó .flush() no. $ Flush() btw, và không, không hoạt động, nhận được lỗi "No pending request to flush", xem: https://github.com/angular/angular.js/issues/2431 –

+2

$ rootScope. $ digest() là IMO không cần thiết nếu bạn đang thử nghiệm một dịch vụ riêng biệt. –

Các vấn đề liên quan