mardi 22 décembre 2015

Unit testing button click event for multiple buttons in directive

I am trying to unit test an Angular directive with Jasmine, and am having a heck of a time doing so. I've tried multiple Google queries, have found multiple SO questions, and have read multiple general knowledge and how-to articles, but for some reason it's just not clicking.

For starters, I am able to test that the directive renders correctly. So, now I am trying to check that certain variables change values (booleans) when certain buttons are clicked. The directive is a group of 6 buttons. I have assigned each button its own class in order to find which button I want to click, but perhaps I need to use an id instead. I also have ng-click events defined on each button.

The problem I am having is that the value of the variable that's supposed to change, doesn't. Either I am implementing the click event incorrectly or the variable isn't bound correctly. The directive works as expected in the actual application, at least from a visual standpoint.

directive.js

(function() {
    /**
     * Log Slider Directive
     * @namespace Directives
     */
    angular
        .module('app')
        .directive('logSlider', logSlider);

    function logSlider() {
        function link(scope, elm) {
            angular.element(elm).on('click', function() {
                scope.trace = !scope.trace;
                scope.debug = !scope.debug;
                scope.info = !scope.info;
                scope.warn = !scope.warn;
                scope.error = !scope.error;
                scope.fatal = !scope.fatal;

                scope.$digest();
            });
        }

        var directive = {
            restrict: 'AE',
            link: link,
            templateUrl: 'src/app/partials/logSlider/logSlider.html',
            scope: {
                trace: "=",
                debug: "=",
                info: "=",
                warn: "=",
                error: "=",
                fatal: "="
            }
        };

        return directive;
    }
})();

directive.html

<div class="btn-group">
    <button class="btn btn-xs traceButton" ng-class="{'btn-secondary':trace, 'btn-default':!trace}" ng-click="trace=false; debug=true; info=true; warn=true; error=true; fatal=true;">TRACE</button>
    <button class="btn btn-xs debugButton" ng-class="{'btn-secondary':debug, 'btn-default':!debug}" ng-click="trace=true; debug=false; info=true; warn=true; error=true; fatal=true;">DEBUG</button>
    <button class="btn btn-xs infoButton" ng-class="{'btn-info':info, 'btn-default':!info}" ng-click="trace=true; debug=true; info=false; warn=true; error=true; fatal=true;">INFO</button>
    <button class="btn btn-xs warnButton" ng-class="{'btn-warning':warn, 'btn-default':!warn}" ng-click="trace=true; debug=true; info=true; warn=false; error=true; fatal=true;">WARN</button>
    <button class="btn btn-xs errorButton" ng-class="{'btn-danger':error, 'btn-default':!error}" ng-click="trace=true; debug=true; info=true; warn=true; error=false; fatal=true;">ERROR</button>
    <button class="btn btn-xs fatalButton" ng-class="{'btn-danger':fatal, 'btn-default':!fatal}" ng-click="trace=true; debug=true; info=true; warn=true; error=true; fatal=false;">FATAL</button>
</div>

directive.spec.js

describe('logSlider directive', function() {
    var compile,
        scope,
        element;


    beforeEach(module('app')); // define module 
    beforeEach(module('src/app/partials/logSlider/logSlider.html')); // location of directive template

    beforeEach(function() {
        inject(function($templateCache, $compile, $rootScope) {
            template = $templateCache.get('src/main/webapp/src/app/partials/logSlider/logSlider.html');
            $templateCache.put('src/main/webapp/src/app/partials/logSlider/logSlider.html', template);
            compile = $compile;
            scope = $rootScope.$new();
            scope.buttons = { // set values for directive's global variables
                trace: false,
                debug: true,
                info: true,
                warn: true,
                error: true,
                fatal: true
            };
            element = angular.element('<log-slider trace="activeTrace" debug="activeDebug" info="activeInfo" warn="activeWarn" error="activeError" fatal="activeFatal"></log-slider>');
            compiledElement = compile(element)(scope);
            scope.$digest();
        });
    });

    // check that the directive renders correctly
    it('should render', function() {
        expect(compiledElement).toBeDefined();
        expect(compiledElement.text()).toContain('TRACE');
    });

    // test that the value for trace changes when certain buttons are clicked
    describe('$scope.trace', function() {
        it('should default to false', function() {
            expect(scope.buttons.trace).toBe(false);
            expect(scope.buttons.trace).not.toBeTruthy();
        });

        it('should change to true when any other slider button is clicked', function() {
            var button = compiledElement[0].querySelectorAll('.warnButton'); // find the button to be clicked
            angular.element(button).triggerHandler('click'); // click the button
            scope.$digest();
            expect(angular.element(button).hasClass('warnButton')).toBe(true); // check to see that the correct button was clicked
            expect(scope.buttons.trace).toBe(true); // check to see if the variable changed after button click
        });

        it('should change to false when clicked', function() {

        });
    });
});

Aucun commentaire:

Enregistrer un commentaire