2013-06-26 3 views
5

Я новичок программист, который очень новичок и для AngularJS, и для практики модульного тестирования. Я потратил часы, пытаясь найти решение этого, но я становлюсь все более запутанным. Если бы кто-нибудь мог указать мне в правильном направлении, я был бы очень признателен. Я постараюсь быть максимально описательным.Karma/Jasmine Unit Тестирование услуги AngularJS с зависимостями

Ситуация такова:

Я создал службу в AngularJS (Service A), который имеет несколько функций. Каждая из этих функций делает запрос HTTP HTTP для API REST и возвращает объект обещания $ http, содержащий данные JSON. Внутри этих функций URL-адрес создается через реализацию другой очень простой службы (Service B), которая была введена как зависимость в Service A. Я создал макет службы B, чтобы изолировать ее от всех ее зависимостей. Обе эти службы определены внутри одного модуля с именем «services». В этом случае нет реальной потребности в этой зависимости, но я просто хочу понять, как это работает.

Использование Jasmine, я хотел бы построить единичный тест для службы A, чтобы гарантировать, что запросы, которые он создает в API, построены правильно и, возможно, если вернутся правильные данные JSON. В то же время я не хочу, чтобы какие-либо реальные вызовы API были сделаны.

Это то, что я знаю:

$ httpBackend фиктивным является то, что мне нужно, чтобы быть в состоянии сделать поддельные звонки в API и предоставляет функциональные возможности ожидать определенные запросы и возврата указанных результатов.

Мне нужно протестировать настоящую службу A и ввести макет, который я создал из службы B. Я знаю, что есть способы сделать это, используя Jasmine Spies и $ обеспечивают. Я также видел примеры использования sinon.js, и я не уверен, что это лучший подход.


Я напишу свой исходный код ниже, который написан на CoffeeScript.

Service 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) 
    ]) 

Service 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}" 
    ] 

ответ

4

так вы говорите, что вы знаете, как сделать это с $ обеспечивают/Jasmine шпионами и ищут альтернативы ? В основном я использовал метод $ provision/spy для насмешек, и до сих пор он очень хорошо работал для меня.

что-то вроде:

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... 
}); 

затем, если вы хотите использовать $ httpBackend издеваться запросов HTTP в услуге А, вам просто необходимо воспользоваться услугой $ форсунки, чтобы захватить $ httpBackend, а затем вызвать .when (...) на нем, чтобы установить вещи, a la http://docs.angularjs.org/api/ngMock.$httpBackend

Смежные вопросы