Angularjs 单元测试 - 向 textarea 添加文本时 ng-disabled 不起作用
Angularjs unit testing - ng-disabled not working when adding text to textarea
我正在尝试使用 karma、mocha、power-assert 测试 AngularJS 组件。
我的组件中有一个文本区域和一个按钮,其中按钮根据文本区域中文本的长度被禁用。
当我 运行 组件在浏览器中时,它工作得很好。但是我不知道如何测试这个功能。
这是一些代码。
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);
});
});
});
正如您在上面的评论中看到的,第二个测试失败了。我猜测试失败了,因为 html 的状态没有反映到组件控制器 inquiryForm
。当然,textarea 的 DOM 正在更新,但是 ng-disabled
指令不会触发,因为组件控制器 inquiryForm
没有连接到范围。
如何在 textarea 中使用模拟用户输入使这个 ng-disabled 触发...
使用如下命名表格:
<form name="inquiry form" ng-submit="inquiryForm.handleSubmit()" method="post">
经过大量的搜索和反复试验,我终于找到了解决方案。正如我所猜测的,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);
});
参考:
我正在尝试使用 karma、mocha、power-assert 测试 AngularJS 组件。 我的组件中有一个文本区域和一个按钮,其中按钮根据文本区域中文本的长度被禁用。
当我 运行 组件在浏览器中时,它工作得很好。但是我不知道如何测试这个功能。
这是一些代码。
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);
});
});
});
正如您在上面的评论中看到的,第二个测试失败了。我猜测试失败了,因为 html 的状态没有反映到组件控制器 inquiryForm
。当然,textarea 的 DOM 正在更新,但是 ng-disabled
指令不会触发,因为组件控制器 inquiryForm
没有连接到范围。
如何在 textarea 中使用模拟用户输入使这个 ng-disabled 触发...
使用如下命名表格:
<form name="inquiry form" ng-submit="inquiryForm.handleSubmit()" method="post">
经过大量的搜索和反复试验,我终于找到了解决方案。正如我所猜测的,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);
});
参考: