Sono un programmatore alle prime armi, che è molto nuovo sia per AngularJS che per la pratica dei test delle unità. Ho passato ore a cercare di trovare la soluzione, ma mi sento sempre più confuso. Se qualcuno potesse indicarmi la giusta direzione lo apprezzerei molto. Cercherò di essere il più descrittivo possibile.Unità Karma/Jasmine Test di un servizio AngularJS con dipendenze
La situazione è questa:
ho creato un servizio in AngularJS (Service A), che ha un paio di funzioni. Ognuna di queste funzioni effettua una richiesta GET $ http a un'API REST e restituisce un oggetto promessa $ http che contiene dati JSON. All'interno di queste funzioni, l'URL viene costruito attraverso l'implementazione di un altro servizio molto semplice (servizio B) che è stato iniettato come dipendenza nel servizio A. Ho creato una simulazione di servizio B per isolarlo da tutte le sue dipendenze. Entrambi questi servizi sono definiti all'interno dello stesso modulo denominato "servizi". In questo caso, non c'è un reale bisogno di questa dipendenza, ma voglio solo capire come funziona.
Utilizzando Jasmine, vorrei creare un test unitario per il servizio A per garantire che le richieste che sta apportando all'API siano costruite correttamente e possibilmente se vengono restituiti i dati JSON corretti. Allo stesso tempo, non voglio che vengano fatte delle vere e proprie chiamate API.
Questo è quello che so:
$ httpBackend finto è quello che ho bisogno di essere in grado di effettuare chiamate falsi per l'API e fornisce funzionalità di aspettarsi alcune richieste e restituire i risultati previsti.
Ho bisogno di testare il vero Servizio A e di iniettare la simulazione che ho creato del Servizio B. So che ci sono modi per farlo usando Jasmine Spies e $ provide. Ho anche visto esempi in cui viene utilizzato sinon.js e non sono sicuro quale sia l'approccio migliore.
Inserirò il mio codice sorgente qui sotto, che è scritto in CoffeeScript.
Servizio 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)
])
Servizio 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}"
]