我是一个新手程序员,对 AngularJS 和单元测试的实践都很陌生。我花了几个小时试图找到解决方案,但我变得越来越困惑。如果有人能指出我正确的方向,我将不胜感激。我会尽量做到描述性。
情况是这样的:
我在 AngularJS(服务 A)中创建了一个具有几个功能的服务。这些函数中的每一个都向 REST API 发出 $http GET 请求,并返回一个包含 JSON 数据的 $http 承诺对象。在这些函数中,URL 是通过另一个非常简单的服务(服务 B)的实现来构造的,该服务已作为依赖项注入到服务 A 中。我创建了服务 B 的模拟以将其与其所有依赖项隔离。这两个服务都定义在同一个名为“services”的模块中。在这种情况下,并没有真正需要这种依赖,但我只想了解它是如何工作的。
使用 Jasmine,我想为服务 A 构建一个单元测试,以确保它向 API 发出的请求是正确构造的,并且可能会返回正确的 JSON 数据。同时,我不希望进行任何真正的 API 调用。
这是我所知道的:
$httpBackend 模拟是我需要能够对 API 进行虚假调用的东西,它提供了预期某些请求并返回指定结果的功能。
我需要测试真正的服务 A 并注入我创建的服务 B 的模拟。我知道使用 Jasmine Spies 和 $provide 可以做到这一点。我还看到了使用 sinon.js 的示例,但我不确定哪种方法最好。
我将在下面发布我的源代码,它是用 CoffeeScript 编写的。
服务一:
'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)
])
服务乙:
'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}"
]