我有一个 Controller ,它依赖于通过 ngResource 构建的服务。我在测试这个时遇到了麻烦(尽管在实际应用程序中两者看起来都很有魅力)。以下是(经过 sanitizer 的) Controller
MyApp.Controller.MyCarsController = (scope, http, typeService) ->
if scope.context==undefined
scope.ferrari_or_porshe =""
scope.id = ""
else if scope.context=="ferrari"
scope.country_or_pi ="Ferrari"
else if scope.context=="porshe"
scope.country_or_pi ="Porshe"
typeService.index
ferrari_or_porshe: scope.ferrari_or_porshe
id: scope.id
, (response) ->
scope.type = response
scope.loading = false
MyApp.Controller.MyCarsController.$inject = ['$scope', '$http', 'Type']
这是服务:
MyApp.MyModule.factory 'Type', ['$resource', ($resource) ->
TypeResource = $resource("/api/types/:ferrari_or_porshe/:id", {},
index:
method: "GET"
isArray: true
)
return TypeResource
]
最后是一些测试代码:
describe 'MyApp.Controller.MyCarsController', ->
beforeEach module('MyModule')
beforeEach inject ($rootScope, $http, $controller, Type) ->
@scope = $rootScope.$new()
@typeService = Type
@scope.context = undefined
$controller 'MyApp.Controller.MyCarsController', $scope: @scope
describe '#home-page', ->
it 'contains a list of types', ->
expect(@scope.types.length).toBeGreaterThan 0
it "sets instance variables correctly", ->
expect(@scope.ferrari_or_porshe).toBe ""
expect(@scope.id).toBe ""
失败的是:
No more request expected in helpers/angular-mocks.js on line 889
TypeError: 'undefined' is not an object (evaluating 'this.scope.types.length') in controllers/my_cars_controller_spec.js
通过明智地应用 console.logs,我发现问题是永远不会到达响应的最终回调。 TypeResource 作为 [Function] 返回。
我的问题是:
如何驱动 Jasmine 测试以正确进入服务并获取响应?有什么方法可以为服务创建直接的单元测试吗?
感谢任何帮助
最佳答案
解决方案如下:对于服务,使用作为 ngMock 一部分捆绑的 $httpBackend:
使用它来模拟 Rest 响应。因为在我的例子中,我只关心验证 GET 请求是否发出:
describe 'Type', ->
describe '#index', ->
beforeEach module('MyModule')
beforeEach inject(($httpBackend) ->
$httpBackend.whenGET('/api/types/ferrari/1').respond([])
)
it 'for a ferrari scope', inject((Type) ->
ferrari_or_porsche = 'ferrari'
id = '1'
expect( Type.index('ferrari_or_porsche': ferrari_or_porsche, 'id': id) ).toEqual([ ])
)
然后对于 Controller ,使用 jasmine spies 模拟服务并使用 jasmine.any(Function)
警告回调。
describe 'MyApp.Controller.MyCarsController', ->
beforeEach module('myModule')
beforeEach inject ($rootScope, $http, $controller, Type) ->
@scope = $rootScope.$new()
@typeService = Type
@scope.context = undefined
spyOn(@typeService, 'index')
describe '#home-page', ->
beforeEach inject ($controller) ->
$controller 'MyApp.Controller.MyCarsController', $scope: @scope
it 'contains a list of types', ->
expect(@typeService.index).toHaveBeenCalledWith({ ferrari_or_porsche : '', id : '' }, jasmine.any(Function))
it "sets instance variables correctly", ->
expect(@scope.ferrari_or_porsche).toBe ""
expect(@scope.id).toBe ""
注意:我对这个解决方案的“规范性”不做任何声明。但它有效。 注意:API 端点当然在其他地方进行了广泛测试。
关于coffeescript - 如何测试依赖于 ngResource 服务的 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13262094/