mardi 26 janvier 2016

Using toThrowError testing directive in Jasmine 2.4.1

I am testing a directive input parameters and throwing new Error() if they are invalid. I am using Jasmine 2.4.1 and Angular 1.4.9

If my directive has templateUrl defined, the exception is recognized by Jasmine because the exception object is instanceof Error.

However, if my directive doesn't have templateUrl defined (because I am creating directive without template), the exception is not recognized by Jasmine, because the exception object is not instanceof Error.

I found this by looking at Jasmine source code of function toThrowError() where the throw variable in former case is instaceof Error, but in latter is not. Here is the code from Jasmine toThrowError():

try {
    actual();
} catch (e) {
    threw = true;
    thrown = e;

    // I added this for testing purposes
    console.log(thrown);
}

if (!threw) {
    fail.message = 'Expected function to throw an Error.';
    return fail;
}

if (!(thrown instanceof Error)) {
    fail.message = function() {
        return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.';
    };
    return fail;
}

My directive with templateUrl (test works as expected):

angular.module('sharedElements', []);

angular.module('sharedElements')
    .directive('cLabel', function () {
        return {
            restrict: 'A',
            scope: {
                label: '='
            },
            templateUrl: 'Client/shared/common/directives/label/label.html',
            controller: ['$scope', function ($scope) {
                if (typeof $scope.label === 'undefined')
                      throw new Error('"label" is undefined');
            }]
        };
    });

My directive without templateUrl (test doesn't work):

angular.module('sharedElements', []);

angular.module('sharedElements')
    .directive('cLabel', function () {
        return {
            restrict: 'A',
            scope: {
                label: '='
            },
            controller: ['$scope', function ($scope) {
                if (typeof $scope.label === 'undefined')
                      throw new Error('"label" is undefined');
            }]
        };
    });

My test:

    describe('cLabel', function () {

        var directiveElement;
        var scope;

        beforeEach(module('sharedElements'));

        function compileDirective() {        
            var element = angular.element('<span data-c-label data-label="label"></span>');

            inject(function ($compile) {
                directiveElement = $compile(element)(scope);
            });

            scope.$digest();
        }

        beforeEach(inject(function ($rootScope) {
            scope = $rootScope.$new();
        }));

        describe('errors', function () {
            it('when "label" is undefined, directive should throw error', function () {
                expect(function () {
                     compileDirective();    
                }).toThrowError('"label" is undefined');
            });
        });
   });

Does anyone know why is this happening?

Thank you!

Aucun commentaire:

Enregistrer un commentaire