Si-N
Si-N

Reputation: 1495

Testing route resolve in Angular

I am trying to test some conditions I have in a resolve on a route:

app.js

$routeProvider.when('/:room/login/', {
        templateUrl: '/app/login/login.html',
        controller: 'LoginCtrl',
        resolve: {
            auth: ['$q', 'RoomService', 'LoginService', '$location', '$route', function ($q, RoomService, LoginService, $location, $route) {
                return RoomService.checkIfRoomExists($route.current.params.room).then(function (success) {
                    if (success === false) {
                        $location.path('/notFound');
                        $location.replace();
                        return $q.reject();
                    }
                    else
                    {
                        return LoginService.isUserLoggedIn().then(function (isloggedin) {
                                if (isloggedin === true) {
                                    var currentPath = $location.path();
                                    $location.path($route.current.params.room);
                                    $location.replace();
                                    return $q.reject();
                                }
                            }, function (err) {
                                return $q.reject(err);
                            })
                    }
                },
                    function (err) {
                        return $q.reject(err);
                    })
            }]
        }
    })

This is my test:

    describe('LoginRoute', function()
    {
        beforeEach(module('corpusRoom'));

        var mockHttp, location, route, rootScope, loginService, roomService;

        beforeEach(inject(function($httpBackend, $location, _$route_, $rootScope, LoginService, RoomService){
            mockHttp = $httpBackend;
            location = $location;
            route = _$route_;
            rootScope = $rootScope;
            spyOn(LoginService, 'isUserLoggedIn');
            spyOn(RoomService, 'checkIfRoomExists');
            loginService = LoginService;
            roomService = RoomService;
        })); 

        it('should check if room exists', function(done)
        {
            location.path('/anyroom/login');
            rootScope.$apply();
            expect(roomService.checkIfRoomExists).toHaveBeenCalled();
            done();
        });
});

But when I run this in Karma it reports this error

TypeError: RoomService.checkIfRoomExists(...).then is not a function at $routeProvider.when.resolve.auth (public/app/app.js:14:86)

The resolve finds the injected RoomService fine when I run it outside of testing.

Can you see why it can't resolve RoomService?

Upvotes: 0

Views: 522

Answers (1)

rrd
rrd

Reputation: 5957

It's the 'then' that is falling down, which you need to mock, so for example:

beforeEach(() => {
  angular.mock.module(services, ($provide) => {
    let RoomService = jasmine.createSpyObj('RoomService', ['checkIfRoomExists']);
    RoomService.checkIfRoomExists.and.returnValue(
      {
        then: () => ({
          catch: () => true
        })
      }
    );
    $provide.value('RoomService', RoomService);
  });
});

Then you won't need to inject RoomService, as $provide will do it for you. Then you Spy should work (I haven't tested this out though) because .then() will be mocked correctly.

Upvotes: 1

Related Questions