Обновление шаблона и вызов $ digest не вызывают $ watch с правильными параметрами - модульные тесты angularjs - PullRequest
0 голосов
/ 13 января 2020

У меня есть простая директива, которая добавляет или удаляет класс focus к элементу на основе свойства scope директивы.

Я бы хотел написать 2 теста.

Сначала проверьте, что класс focus включен в элемент, когда для свойства scope.addFocus установлено значение 'true'. Этот тест проходит.

Затем я обновляю скомпилированный шаблон директивы, меняю свойство scope.addFocus на 'false', запускаю $digest() и ожидаю, что директива обновит классы элемента и удалит класс focus. Этот тест не пройден.

Вот ссылка на plunkr: http://plnkr.co/edit/k4PBcCwfivsJsbIEUwGd?p=preview

Есть идеи, почему $compiledTemplate.attr('add-focus', 'false'); $directiveScope.$digest(); не будет обновлять классы обновления должным образом?

Код директивы

myApp.directive('myDirective', function() {
    return {
        scope: {
            addFocus: '@'
        },
        restrict: 'A',
        link: function (scope, element, attr) {

            scope.$watch(
                function() { return scope.addFocus; },
                function (newValue, oldValue) {

                    if (newValue === 'true') {
                        element.addClass('focus');
                    } else {
                        element.removeClass('focus');
                    }
                },
                false
            );
        }
    };
});

Испытания

describe('myApp', function () {

  var $compile, $timeout, $rootScope;
  var $directiveScope;

  var template = '<div my-Directive add-focus="true"></div>';
  var $compiledTemplate;

  beforeEach(function () {
      module('myApp');
  });

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

  beforeEach(function() {
      $directiveScope = $rootScope.$new();
      $compiledTemplate = $compile(template)($directiveScope);
      $directiveScope.$digest();
  });

  // Test 1
  it('directive is compiled and has focus class', function() {
      console.log('test1', $compiledTemplate[0]);
      expect($compiledTemplate.hasClass('focus')).toBe(true);
  });

  // Test 2
  it('focus class is removed', function() {
      $compiledTemplate.attr('add-focus', 'false');
      $directiveScope.$digest();

      $timeout(function() {
          console.log('test2', $compiledTemplate[0]);
          expect($compiledTemplate.hasClass('focus')).toBe(false);
      }, 0);

      $timeout.flush();
  });

});

Ответы [ 2 ]

1 голос
/ 13 января 2020

Ответ дан и принят, хотя это и не хорошо: когда вы тестируете директиву с помощью ввода - тестируйте ввод, не изменяйте область действия директивы напрямую.

и самый короткий пример:

beforeEach(function() {
    $upperScope = $rootScope.$new();
    $upperScope.param = true;
    $compiledTemplate = $compile('<div my-Directive add-focus="{{param}}"></div>')($upperScope);
    $upperScope.$digest();
});

// Test 1
it('directive is compiled and has focus class', function() {
    expect($compiledTemplate.hasClass('focus')).toBe(true);
});

// Test 2
it('focus class is removed', function() {
    $upperScope.param = false; 
    $upperScope.$digest();

    expect($compiledTemplate.hasClass('focus')).toBe(false);
});    
0 голосов
/ 13 января 2020

Обновлен Plunker

Проблема, когда наблюдатель не получал сам вызов. Нам нужно использовать isolateScope для того же. Я создал isolateScope, как показано ниже:

        isolateScope = $compiledTemplate.isolateScope();

и переключил значение addFocus в spe c, чтобы вызвать срабатывание наблюдателя

        isolateScope.addFocus = false;
...