Christopher Fus
Christopher Fus

Reputation: 3

Unit testing Angular controller with Jasmine

I have been trying to write unit tests for js code from the Spring-boot tutorial: http://spring.io/guides/tutorials/spring-security-and-angular-js/

What I want to do i to fake the response from /user as a 200 response so I can test that the controller sets $rootScope.authenticated = true

Here is hello.js:



    angular.module('hello', [ 'ngRoute' ]).config(function($routeProvider) {
        $routeProvider.when('/', {
            templateUrl : 'home.html',
            controller : 'home'
        }).otherwise('/');

    }).controller('navigation', function($rootScope, $scope, $http, $location, $route) {

        $scope.tab = function(route) {
            return $route.current && route === $route.current.controller;
        };

        $http.get('/user').success(function(data) {
            if (data.name) {
                $rootScope.authenticated = true;
            } else {
                $rootScope.authenticated = false;
            }
        }).error(function() {
            $rootScope.authenticated = false;
        });

        $scope.credentials = {};

        $scope.logout = function() {
            $http.post('/logout', {}).success(function() {
                $rootScope.authenticated = false;
                $location.path("/");
            }).error(function(data) {
                console.log("Logout failed")
                $rootScope.authenticated = false;
            });
        }

    }).controller('home', function($scope, $http) {
        $http.get('/resource').success(function(data) {
            $scope.greeting = data;
        })
    });

I am trying to mock the response from the GET call on the endpoint: /user and force the controller to direct to the flow for authenticated users.

Corresponding Jasmine spec:



    describe('UiApplicationTest', function() {
        var scope;
        var $httpBackend, $controller;

        beforeEach(module('hello'));

        beforeEach(inject(function(_$rootScope_, _$controller_, _$httpBackend_) {
            $controller = _$controller_;
            $httpBackend = _$httpBackend_;
            scope = _$rootScope_;
        }));

        afterEach(function() {
            $httpBackend.verifyNoOutstandingExpectation();
            $httpBackend.verifyNoOutstandingRequest();
        });

        describe('Should authentication details be provided', function() {

            beforeEach(function() {
                // Taking care for requests not in the scope of the test
                $httpBackend.whenGET(/\.html$/).respond('');
                // Mocking request under test
                $httpBackend.whenGET('/user').respond(200, 'user');
                $controller('navigation', { $scope: scope });

                // Launching the request
                $httpBackend.expectGET('/user');
                $httpBackend.flush();
            });

            it('user shall grant access', function() {
                expect(scope.authenticated).toBe(true);
            });
        });
    });

Problem is that the I do not get the expected result. Assertion is: Expected false to be true.

I have spent several hours on this already reading various manuals and posts. Clearly I do not understand something here. Can somebody point me my mistake?

Upvotes: 0

Views: 387

Answers (1)

JulCh
JulCh

Reputation: 2888

It seems that your $rootScope.authenticated is true when the name property in the response data is defined. However, your mock on '/user' just return 'user'.

Try this :

$httpBackend.whenGET('/user').respond(200, {'name':'user'});

Hope it helps !

Upvotes: 1

Related Questions