Как unit test угловая форма?
Я изучаю AngularJS, и все идет довольно гладко относительно модульного тестирования, но я достиг немного сложного места.
Предположим, что у меня простая форма, например:
<form name="form">
<input type="text" name="number" ng-pattern="/^d+$/">
</form>
Если я тестировал что-то вроде контроллера, я знаю, что я напишу ему что-то вроде этого (используя Jasmine + Karma):
beforeEach(module('some.module'));
beforeEach(inject(/* services */) {
/* inject necessary services */
});
it('should be invalid when given bad input', function () {
form.number = 'Not a number';
expect(form.number.$valid).toBeFalsy();
expect(form.$valid).toBeFalsy();
});
Но я не знаю, какие услуги мне нужно вводить, и мне не повезло найти документацию по модульному тестированию в руководстве forms
. или документации ng-form
.
Как одна unit test форма в Angular?
Ответы
Ответ 1
Я не уверен, что это лучший способ unit test что-то вроде этого, но с некоторой помощью от этого ответа при тестировании пользовательских директив angular и некоторых эксперимент, я понял способ unit test формы.
После установки karma-ng-html2js-preprocessor
и настройки, мне удалось получить рабочий unit test следующим образом:
var scope, form;
beforeEach(function() {
module('my-module');
module('templates');
});
beforeEach(inject($rootScope, $controller, $templateCache, $compile) {
scope = $rootScope.$new()
ctrl = $controller('MyController'), {
"$scope": scope
}
templateHtml = $templateCache.get('path/to/my/template.html')
formElem = angular.element("<div>" + templateHtml + "</div>")
$compile(formElem)(scope)
form = scope.form
scope.$apply()
}
it('should not allow an invalid `width`', function() {
expect(form.$valid).toBeTruthy();
form.number.$setViewValue('BANANA');
expect(form.number.$valid).toBeFalsy()
});
Ответ 2
Я думаю, я могу добавить некоторые детали к принятому ответу: karma-ng-html2js-preprocessor должен быть настроен в файле karma.conf.js аналогичным образом:
//karma.conf.js
ngHtml2JsPreprocessor: {
moduleName: 'templates'
},
files: [
//... other files
//my templates
'app/**/*.html'
],
preprocessors: {
'app/**/*.html': ['ng-html2js']
},
plugins: [
//... other plugins
"karma-ng-html2js-preprocessor"
]
Ответ 3
Вот способ unit test с формой angular без необходимости компиляции шаблона контроллера. Хорошо работает для меня в моем ограниченном использовании.
describe('Test', function() {
var $scope, fooController;
beforeEach(function($rootScope, $controller, formDirective) {
$scope = $rootScope.$new();
fooController = $controller('fooController', {$scope: $scope});
// we manually create the form controller
fooController.form = $controller(formDirective[0].controller, {
$scope: $scope,
$element: angular.element("<form></form>"),
$attrs: {}
});
});
it('should test something', function() {
expect(fooController.form.$valid).toBeFalsy();
});
});
Ответ 4
В качестве альтернативы, если вы используете WebPack с помощью karma-webpack
- вы можете включить шаблон с require
, без необходимости пакета karma-ng-html2js-preprocessor
:
describe("MyCtrl form", function () {
var $scope,
MyCtrl;
beforeEach(angular.mock.module("my.module"));
beforeEach(inject(function (_$rootScope_, _$controller_, _$compile_) {
$scope = _$rootScope_.$new();
// Execute the controller logic
// Omit the ' as vm' suffix if you are not using controllerAs
MyCtrl = _$controller_("MyCtrl as vm", { $scope: $scope });
// Compile the template against our scope to populate form variables
var html = require("./my.template.html"),
template = angular.element(html);
_$compile_(template)($scope);
}));
it('should be invalid when given bad input', function () {
MyCtrl.form.number.$setViewValue('Not a number');
expect(MyCtrl.form.number.$valid).toBeFalsy();
expect(MyCtrl.form.$valid).toBeFalsy();
});
});
HTML:
<form name="vm.form">
<input type="text" name="number" ng-pattern="/^d+$/">
</form>