0

I am trying to unit-testing for following code, I wrote following code for unit-testing like below, I have tried so many ways to work, but I keep getting error:

'Cannot read property 'num' of undefined'

I do not know why scope is not properly set. If you have any idea about it, can you please give some advices?

var angular = require('angular');
require('angular-mocks');

describe('test directive', function () {

    let $rootScope;
    let $compile;
    let scope;
    let newScope;
    let element;

    beforeEach(angular.mock.inject(function (_$compile_, _$rootScope_) {
        $compile = _$compile_;
        $rootScope = _$rootScope_;
    }));

    describe('test directive', function () {

        beforeEach(function () {
            newScope = $rootScope.$new();
            element = $compile('<test-directive></test-directive>')(newScope);
            newScope.$digest();
            scope = element.isolateScope();
        });

        fit('scope initialized', function () {
            expect(scope.num).toEqual(1);
        });

    });
});
module.exports = module.directive('testDirective', ['$rootScope', '$scope', function($rootScope, $scope) {

    return {
        template: require('./test.html'),
        restrict: 'E',
        controller: [
            '$scope',
            function ($scope) {
                    $scope.num = 1

                    $scope.sum = function(a, b) {
                        return a + b;
                    }

            }]
    }
}]);
georgeawg
  • 48,608
  • 13
  • 72
  • 95
Anna Lee
  • 909
  • 1
  • 17
  • 37

1 Answers1

0

The scope variable is undefined because the directive being tested does not have an isolate scope. Instead, use the scope of the element:

    beforeEach(function () {
        newScope = $rootScope.$new();
        element = $compile('<test-directive></test-directive>')(newScope);
        newScope.$digest();
        ̶s̶c̶o̶p̶e̶ ̶=̶ ̶e̶l̶e̶m̶e̶n̶t̶.̶i̶s̶o̶l̶a̶t̶e̶S̶c̶o̶p̶e̶(̶)̶;̶
        scope = element.scope();
    });

    fit('scope initialized', function () {
        expect(scope.num).toEqual(1);
    });

Be aware that directive has a fatal flaw. It can only use it once within a given scope.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • Yes, I was able to get something from it, but it returns ChildScope not Scope, do you know why this happens? – Anna Lee Nov 06 '19 at 21:22
  • It returns a `ChildScope` because it inherits properties from `$rootScope`. – georgeawg Nov 06 '19 at 23:25
  • newScope should be Childscope but scope should be element specific scope, but it is not. – Anna Lee Nov 07 '19 at 00:38
  • No scope will be created for the directive when the `scope` property is omitted from the Directive Definition Object. See [AngularJS Comprehensive Directive API Reference - `scope`](https://docs.angularjs.org/api/ng/service/$compile#-scope-). – georgeawg Nov 07 '19 at 00:59
  • I actually have tried it, scope: {} like this. but it still does not work, will look into it more. – Anna Lee Nov 07 '19 at 01:04