Testing Angular controllers with Jasmine

Drop in your code, drop in your Jasmine specs, and away you go!

by munir

HTML

<script src="http://pivotal.github.io/jasmine/lib/jasmine-1.3.1/jasmine.js"></script>
<script src="http://pivotal.github.io/jasmine/lib/jasmine-1.3.1/jasmine-html.js"></script>
<link rel="stylesheet" href="http://pivotal.github.io/jasmine/lib/jasmine-1.3.1/jasmine.css">
<script src="http://code.angularjs.org/1.0.5/angular.js"></script>
<script src="http://code.angularjs.org/1.0.5/angular-mocks.js"></script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    
    <head>
        <title>Jasmine Spec Runner</title>
        <script type="text/javascript">
            (function() {
                var jasmineEnv = jasmine.getEnv();
                jasmineEnv.updateInterval = 1000;

                var htmlReporter = new jasmine.HtmlReporter();

                jasmineEnv.addReporter(htmlReporter);

                jasmineEnv.specFilter = function(spec) {
                    return htmlReporter.specFilter(spec);
                };

                var currentWindowOnload = window.onload;

                window.onload = function() {
                    if (currentWindowOnload) {
                        currentWindowOnload();
                    }
                    execJasmine();
                };

                function execJasmine() {
                    jasmineEnv.execute();
                }

            })();
        </script>
    </head>
    
    <body></body>

</html>

JavaScript

//--- CODE --------------------------
(function (angular) {
    function MyCtrl($scope) {
        $scope.name = 'Superhero';
        $scope.counter = 0;
        $scope.$watch('name', function (newValue, oldValue) {
            $scope.counter = $scope.counter + 1;
        });
    }
    var myApp = angular.module('myApp', []);

    myApp.controller('MyCtrl', MyCtrl);

    myApp.controller('CtrlHttp', function ($http, $scope, $q) {
        var state;
        $scope.getState = function () {
            return state;
        };
        $scope.getHttp = function (value) {

            state = value;

            var defer = $q.defer();

            $http({
                method: 'GET',
                url: '/someUrl',
                headers: {
                    'Accept-Language': 'en'
                },
                params: {
                    key1: "value1"
                }
            }).
            success(function (data, status, headers, config) {
                // this callback will be called asynchronously
                // when the response is available
                defer.resolve();
            }).
            error(function (data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                defer.reject();
            });

            return defer.promise;
        };
    });
})(angular);



// ---SPECS-------------------------

describe('myApp', function () {
    var scope;
    var controller;
    var expectedUrl = '/someUrl?key1=value1';
    var $httpBackend;
    beforeEach(function () {
        module('myApp');
    });
    it('sets the name', inject(function ($rootScope, $controller) {
        scope = $rootScope.$new();
        controller = $controller('MyCtrl', {
            '$scope': scope
        });
        expect(scope.name).toBe('Superhero');
    }));
    it('watches the name and updates the counter', inject(function ($rootScope,...