【问题标题】:Angularjs unit testing - ng-disabled not working when adding text to textareaAngularjs单元测试-将文本添加到textarea时禁用ng的不起作用
【发布时间】:2016-11-13 06:38:22
【问题描述】:

我正在尝试使用 karma、mocha、power-assert 测试 AngularJS 组件。 我的组件中有一个 textarea 和一个按钮,根据 textarea 中的文本长度禁用该按钮。

当我在浏览器中运行该组件时,它可以完美运行。但我不知道如何测试这个功能。

这里有一些代码。

inquiryForm.js

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

inquiryForm.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>

inquiryFormTest.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);
    });
  });
});

正如您在上面的 cmets 中看到的,第二个测试失败了。我猜测试失败了,因为 html 的状态没有反映到组件控制器inquiryForm。确定 textarea 的 DOM 正在更新,但 ng-disabled 指令不会触发,因为组件控制器 inquiryForm 未连接到范围。

如何使用 textarea 中的模拟用户输入来使这个 ng-disabled 触发...

【问题讨论】:

  • 你有described 和inquiry form。您是否尝试使用 name="inquiry form" 命名
  • @mattymanme 我不认为 unittest 中 describe 的值可以链接到 Angular js 对象。我确实尝试过,但它没有用。

标签: angularjs unit-testing components karma-mocha


【解决方案1】:

经过大量搜索和反复试验,我终于找到了解决方案。正如我猜测的那样,textarea 中文本的更改没有被传达给组件控制器,因此包含对它的引用的 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

【讨论】:

    【解决方案2】:

    使用如下命名表格:

    <form name="inquiry form" ng-submit="inquiryForm.handleSubmit()" method="post">
    

    【讨论】:

    • 感谢您的回答。这不起作用。即使更改 textarea 的值,ng-disabled 指令也不起作用。
    猜你喜欢
    • 1970-01-01
    • 2013-10-09
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    相关资源
    最近更新 更多