Модульное тестирование Angularjs - ng-disabled не работает при добавлении текста в текстовую область

Я пытаюсь протестировать компонент AngularJS, используя karma, mocha, power-assert. У меня есть текстовое поле и кнопка в моем компоненте, где кнопка отключена в зависимости от длины текста в текстовом поле.

Когда я запускаю компонент в браузере, он работает отлично. Но я не могу понять, как проверить эту функцию.

Вот немного кода.

запросForm.js

function inquiryForm($scope) {
  // i plan to add some logic here
}
angular.module('myApp').component('inquiryForm', {
  controller: inquiryForm,
  controllerAs: 'inquiryForm',
  templateUrl: 'inquiryForm.html'
});

форма запроса.html

<div class="contact">
    <div>Thanks for contacting us.</div>
    <form>
        <textarea ng-model="inquiryForm.inquiryText" name=""></textarea>
        <input type="submit" value="SEND" ng-disabled="!inquiryForm.inquiryText.length">
    </form>
</div>

запросFormTest.js

describe('inquiry form ', () => {
  let $rootScope;
  let $scope;
  let $compile;
  let element;

  beforeEach(() => {
    angular.mock.module('myApp');

    inject(($injector) => {
      $rootScope = $injector.get('$rootScope');
      $scope = $rootScope.$new();
      $compile = $injector.get('$compile');
    });
  });

  const compileDirective = () => {
    element = $compile('<inquiry-form></inquiry-form>')($scope);
    $scope.$digest();
  };

  describe('inquiry form', () => {
    beforeEach(() => {
      compileDirective();
    });

    // this test passes
    it('disables the submit button if textbox is empty', () => {
      assert(element.find('input').prop('disabled'), true);
    });

    // this test fails
    it('enables the submit button if textbox is not empty', () => {
      // making some changes to DOM here
      element.find('textarea').text('hello, world!');
      console.log(element.find('textarea').text()); // expected: "hello, world!", actual: "hello, world!"

      // since the state of scope has changed, I call digest to reflect those 
      $scope.$digest();

      // this assert passes
      assert(element.find('textarea').text(), 'hello, world!');

      // this one fails.
      assert(element.find('input').prop('disabled'), false);
    });
  });
});

Как вы можете видеть в комментариях выше, второй тест не проходит. Я предполагаю, что тест провалился, так как состояние html не было отражено в контроллере компонентов inquiryForm. Конечно, DOM textarea обновляется, но директива ng-disabled не срабатывает, поскольку контроллер компонента inquiryForm не подключен к области.

Как я могу сделать этот огонь с отключенным ng с имитацией пользовательского ввода в текстовой области...


person Community    schedule 11.07.2016    source источник
comment
у вас есть described inquiry form. Вы пытались назвать имя с помощью name="inquiry form"   -  person mattyman    schedule 11.07.2016
comment
@mattymanme я не думаю, что значение describe в unittest может ссылаться на объект angular js. Я пробовал это, хотя, и это не сработало.   -  person    schedule 12.07.2016


Ответы (2)


После долгих поисков, проб и ошибок я наконец нашел решение. Как я и предполагал, изменение текста в текстовом поле не сообщалось контроллеру компонента, поэтому ng-disabled="!inquiryForm.inquiryText.length", который содержит ссылку на него, не срабатывал.

Вот как я изменил свой тестовый код...

// this test fails
it('enables the submit button if textbox is not empty', () => {
  // making some changes to DOM here
  // ↓---↓ REMOVED THIS
  // element.find('textarea').text('hello, world!');
  // ↑---↑ this was just making changes to DOM but was not informing the component controller of those changes.

  // ↓+++↓ ADDED THIS
  angular.element(element.find('textarea')).val('hello, world!').triggerHandler('change');
  // ↑+++↑ I used the .val() and .triggerHandler() of angularjs to inform component of changes in state of scope

  // since the state of scope has changed, I call digest to init the watchers 
  $scope.$digest();

  // now this assert passes
  assert(element.find('input').prop('disabled') === false);
});

ссылка: https://stackoverflow.com/a/26376249/6573907

person Community    schedule 12.07.2016

используйте имя формы, как показано ниже:

<form name="inquiry form" ng-submit="inquiryForm.handleSubmit()" method="post">
person mattyman    schedule 11.07.2016
comment
спасибо за Ваш ответ. Это не работает. Директива ng-disabled не работает даже после изменения значения textarea. - person ; 12.07.2016