1

I'm trying to access the scope.loading variable in my unit test. The idea is to test that the $on listener fires correctly.

scope.loading is defaulted to false in the link function of my directive. It should be updated to true when the $on function receives the 'loadingPosts' $broadcast from $rootScope.

However, the test case always fails saying the scope.loading is undefined. Where am I going wrong?

Here's my test case:

'use strict';

describe('ngPress', function()
{
    beforeEach(module('ngPress'));

    describe('ngpLoader directive', function()
    {
        it('loading event fires', function()
        {
            inject(function($compile, $rootScope)
            {
                var scope = $rootScope.$new();

                var element = $compile('<ngp-loader type=\"posts\"></ngp-loader>')(scope);

                $rootScope.$broadcast( 'loadingPosts' );

                expect( scope.loading ).toEqual( true );
            });
        });
    });
});

And here's the directive:

(function ()
{
    angular.module('ngPress').directive('ngpLoader',
        [function ()
        {
            var link = function(scope, element, attrs)
            {
                scope.loading = false;

                scope.$on( 'loading'+scope.type.capitalizeFirstLetter(), function()
                {
                    scope.loading = true;
                });

                scope.$on( scope.type+'Loaded', function()
                {
                    scope.loading = false;
                });

                scope.$on( scope.type+'LoadFailed', function()
                {
                    scope.loading = false;
                });
            };

            return {
                link: link,
                restrict: 'E',
                replace: true,
                template: '<div class="loader" ng-show="loading"></div>',
                scope: {
                    type: '@'
                }
            };
        }]);
}());

1 Answer 1

2

Your directive creates an isolate scope by using the scope option i.e. scope: { type: '@' }

You can access this scope in a test using element.isolateScope():

var scope = $rootScope.$new();

var element = $compile('<ngp-loader type=\"posts\"></ngp-loader>')(scope);

$rootScope.$broadcast( 'loadingPosts' );

var isolateScope = element.isolateScope();
isolateScope.$apply();
expect( isolateScope.loading ).toEqual( true );

See angular.element docs:

isolateScope() - retrieves an isolate scope if one is attached directly to the current element

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.