2013-06-26 35 views
5

Tôi là lập trình viên mới làm quen với cả AngularJS và thực hành thử nghiệm đơn vị. Tôi đã dành hàng giờ cố gắng tìm ra giải pháp cho điều này nhưng tôi ngày càng trở nên bối rối hơn. Nếu bất cứ ai có thể chỉ cho tôi đúng hướng tôi sẽ đánh giá cao nó. Tôi sẽ cố gắng mô tả càng tốt.Đơn vị Karma/Jasmine Thử nghiệm Dịch vụ AngularJS với Người phụ thuộc

Tình hình là thế này:

Tôi đã tạo ra một dịch vụ trong AngularJS (Service A) mà có một vài chức năng. Mỗi hàm này tạo một yêu cầu GET $ http cho một API REST và trả về một đối tượng lời hứa $ http chứa dữ liệu JSON. Trong các chức năng này, URL được xây dựng thông qua việc triển khai một dịch vụ rất đơn giản khác (Dịch vụ B) đã được tiêm dưới dạng phụ thuộc vào Dịch vụ A. Tôi đã tạo một mô hình Dịch vụ B để cô lập nó khỏi tất cả các phụ thuộc của nó. Cả hai dịch vụ này được định nghĩa bên trong cùng một mô-đun có tên là "dịch vụ". Trong trường hợp này, không có nhu cầu thực sự cho sự phụ thuộc này nhưng tôi chỉ muốn hiểu nó hoạt động như thế nào.

Sử dụng Jasmine, tôi muốn xây dựng một bài kiểm tra đơn vị cho Dịch vụ A để đảm bảo rằng các yêu cầu mà nó đang tạo cho API được xây dựng chính xác và có thể nếu dữ liệu JSON chính xác được trả về. Đồng thời, tôi không muốn thực hiện bất kỳ cuộc gọi API thực sự nào.

Đây là những gì tôi biết:

$ httpBackend giả là những gì tôi cần để có thể thực hiện cuộc gọi giả mạo để API và nó cung cấp chức năng để mong đợi các yêu cầu nhất định và trả lại kết quả cụ thể.

Tôi cần kiểm tra Dịch vụ thực sự A và tiêm mô hình tôi đã tạo Dịch vụ B. Tôi biết có nhiều cách để thực hiện việc này bằng cách sử dụng Jasmine Spies và $ cung cấp. Tôi cũng đã thấy các ví dụ nơi sử dụng sinon.js và tôi không chắc đó là cách tiếp cận tốt nhất.


Tôi sẽ đăng mã nguồn bên dưới, được viết bằng CoffeeScript.

Dịch vụ A:

'use strict' 

angular.module("services") 
    .service("ServiceA", ["$http", "ServiceB", ($http, ServiceB) -> 

    #Uses underscore.js to set this default attribute 
    defaults = withCredentials:true 

    getVarset: (itemName, options={}) -> 
     options.method = "GET" 
     options.url = ServiceB.makeUrl("item/#{itemName}") 

     $http _.defaults(options, defaults) 

    getVarsets: (options = {}) -> 
     options.method = "GET" 
     options.url = ServiceB.makeUrl("items") 

     $http _.defaults(options, defaults) 

    getModelsForVarset: (itemName, options = {}) -> 
     options.method = "GET" 
     options.url = ServiceB.makeUrl("item/#{itemName}/prices") 

     $http _.defaults(options, defaults) 
    ]) 

Dịch vụ B:

'use strict' 

angular.module('services') 
    .service 'ServiceB', [ -> 

    # Just return the string 
    # This service builds the real URL, but I've removed this 
    makeUrl: (Url) -> 
     "#{Url}" 
    ] 

Trả lời

4

như vậy là bạn nói rằng bạn biết làm thế nào để làm điều này với $ cung cấp/gián điệp Jasmine và đang tìm kiếm giải pháp thay thế ? Tôi hầu như chỉ sử dụng phương thức $ cung cấp/gián điệp để chế nhạo và nó đã làm việc rất tốt cho tôi cho đến nay.

cái gì đó như:

beforeEach(function() { 

    // set up a default value for your mock 
    bMock = { 
     makeUrl: jasmine.createSpy('makeUrl() mock').andReturn('http://www....') 
    } 

    // use the $provide service to replace ServiceB 
    // with your mock 
    module('services', function($provide) { 
     $provide.value('ServiceB', bMock); 
    }); 

}); 

it('should do what its supposed to do', function() { 
    // test... 
}); 

sau đó, nếu bạn muốn sử dụng $ httpBackend để thử các yêu cầu http phục vụ A, bạn chỉ cần sử dụng dịch vụ $ injector để lấy $ httpBackend, sau đó gọi .Khi (...) trên đó để thiết lập mọi thứ, a la http://docs.angularjs.org/api/ngMock.$httpBackend

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