Testing AngularJS code that running inside the main module .run method

So I am start to write unit test for an AngularJS application I wrote. This application is protected with a login page so that if the username in not logged in, any request to any page except the login page will redirect the login page. This logic is executed from the main modules .run() method since it only needs to run once, when the application starts, however is there a way to test code that is executed from within the main modules .run() method? I ahve the follow test code:

describe('Login Controller', function(){
    'use strict';

    var scope, controller, $httpBackend, $resource, callback;

    beforeEach(module('application'));

    beforeEach(inject(function($injector, $rootScope, $controller, $http, $location, authentication, session) {
        $httpBackend = $injector.get('$httpBackend');
        $httpBackend.expectGET('/api/v1/authentication').respond({status: 'success', data: null});
        $resource = $injector.get('$resource');
        callback = jasmine.createSpy();
        scope = $rootScope.$new();
        controller = new $controller('Login', {
            $scope: scope,
            $http: $http,
            $location: $location,
            authentication: authentication,
            session: session
        });
    }));

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

    it('should verify all default values for controller', function() {
        expect(scope.username).toEqual('');
        expect(scope.password).toEqual('');
        expect(scope.displayApplicationLoad).toEqual(false);
        expect(angular.isFunction(scope.login)).toEqual(true);
        expect(angular.isFunction(scope.logout)).toEqual(true);
        expect(scope.loggedIn).toEqual(false);
        expect(scope.headerTemplate).toEqual('/templates/core/header.html');
        expect(scope.footerTemplate).toEqual('/templates/core/footer.html');
    });
});

The issue is that the code running inside the main modules .run() method is not taking into account the

$httpBackend.expectGET('/api/v1/authentication').respond({status: 'success', data: null});

line. Should I be placing this logic somewhere else so that I can unit test this code?

I would move all this code that you want to test into a service, which you inject into your run block. Then you can test this service independently. Also you can then set up modules for testing other stuff that relies on authentication more flexibly.

I think I found a way to test a module's run method. It's a little hacky but it gets the job done. Here's my solution:

describe( 'my module', function() {

  var runBlocks;

  beforeEach( function() {
     var myModule = angular.module( 'modules.flow' );

     runBlocks = myModule._runBlocks;
     myModule._runBlocks = [];

     module( 'myModule' );
  } );

  afterEach( function() {
     angular.module( 'modules.flow' )._runBlocks = runBlocks;
  } );

  describe( 'when loaded', function() {

     beforeEach( inject( function( $injector ) {

        // Here you could e.g. configure $httpBackend

        for( var i = 0; i < runBlocks.length; ++i ) {
           $injector.invoke( runBlocks[i] );
        }
     } ) );

     // Tests ...

  } );

} );

First I make a copy of all run blocks defined for the module and delete the internal list of run blocks. Then it is possible to do the setup necessary for the run blocks to succeed and afterwards let the injector invoke the functions.

Nevertheless, if there is any chance to extract the code within the run blocks into appropriate services, you should prefer that way.

Update: Added missing afterEach method

Update 2: Fixed call to angular.module