单元测试AngularJS控制器,其资源使用$ routeParams

时间:2012-11-09 07:45:08

标签: javascript unit-testing angularjs jasmine

注意:我在CoffeeScript中编写所有内容

我有一个控制器如下:

angular.module('myApp').controller 'MyController', ($scope, $routeParams, Batch) ->
    $scope.$on '$routeChangeSuccess', () ->
        Batch.get {batchUuid: $routeParams.batchUuid}, (response) ->
            $scope.batch_id = response.id

控制器提取Batch资源,该资源定义如下:

angular.module('myApp').factory 'Batch', ($resource) ->
    $resource '/batches/:batchUuid', {}

我有这样的路线如下:

$routeProvider.when('/batches/:batchUuid',
    { templateUrl: 'batches-processing.html', controller: 'MyController' })

所以:

  • 您访问路线 / batches / 22
  • 它使用MyController
  • 触发 $ routeChangeSuccess
  • 它调用来自路径
  • 的批处理资源上的batchUuid
  • 它返回一个json响应并为$ scope.batch_id
  • 分配一个id

现在我想测试这个,所以我有一个单元测试如下:

describe 'Controllers', ->
    beforeEach module 'myApp'
        describe 'MyController', ->
            scope = {}
            ctrl= {}

            beforeEach inject ($rootScope, $controller, Batch, $httpBackend) ->
                scope = $rootScope.$new()
                ctrl = $controller('MyController', ($scope: scope))
                #I imagine I need to use either my injected Batch resource or the httpBackend to fake/expect the ajax call here

            it "Gets data from the resource and assigns it to scope", () ->
                #How on earth do I test this

我见过人们使用$ httpBackend.expect('/ endpoint.json')。respond({id:1})等但我不能这样做。我的资源URL依赖于路由中的batchUuid。如何模拟/伪造/实现将模拟路由更改的测试,触发$ routeChangeSuccess,将routeParameter传递给资源,获取资源并测试结果?

我正在把头发拉过来,角度的文档似乎没有覆盖它。

谢谢!

2 个答案:

答案 0 :(得分:10)

你可以制作一个假的routeParams并将其注入你的控制器。

我为我的假货使用茉莉花的createSpy,但这可能有点矫枉过正。有一个示例here,展示了如何创建和注入虚假的routeParams。

答案 1 :(得分:0)

这个js小提示显示了被注入的routeParams:

http://jsfiddle.net/rimian/wgctykea/

it('should take articleId as id if specified', inject(function ($controller) {
  routeParams.articleId = 5;

  ctrl = $controller('MyAppCtrl', {
    $scope: scope,
    $routeParams: routeParams
  });

  expect(scope.id).toEqual(5);
}));