Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Test AngularJS controller with a resource that uses $routeParams

Note: I'm writing everything in CoffeeScript

I have a controller as follows:

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

The controller pulls in the Batch resource which is defined as follows:

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

I have a route for this as follows:

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

So:

  • You visit the route /batches/22
  • It uses MyController
  • It triggers $routeChangeSuccess
  • It calls get on the Batch resource witch the batchUuid from the route
  • It gets back a json response and assigns an id to $scope.batch_id

Now I want to test this so I have a unit test as follows:

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

I have seen people using $httpBackend.expect('/endpoint.json').respond({id:1}) etc but I can't do that. My resource URL relies on a batchUuid from the route. How can I simulate/fake/implement a test that will simulate a route change, trigger the $routeChangeSuccess, pass a routeParameter to the resource, do a get on the resource and test the result?

I'm pulling my hair out over this and angular docs don't seem to cover it.

Thanks!

like image 490
Brad Barrow Avatar asked Nov 09 '12 07:11

Brad Barrow


1 Answers

You can make a fake routeParams and inject it into your controller.

I use jasmine's createSpy for my fakes, but that might be a bit overkill. There's an example here that shows how to create and inject the fake routeParams.

like image 92
Roy Truelove Avatar answered Sep 21 '22 15:09

Roy Truelove