J'ai appris AngularJS et les choses se passent plutôt bien pour les tests unitaires, mais j'ai atteint un point délicat.
Supposons que j'ai un formulaire simple, par exemple:
<form name="form">
<input type="text" name="number" ng-pattern="/^d+$/">
</form>
Si je testais quelque chose comme un contrôleur, je sais que je l'écrirais comme ceci (en utilisant 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();
});
Mais je ne sais pas quels services je dois injecter et je n'ai pas eu la chance de trouver de la documentation sur les tests unitaires dans the forms
guide ou the ng-form
documentation .
Comment une unité teste-t-elle un formulaire en forme angulaire?
Je ne suis pas convaincu que ce soit la meilleure façon de tester un élément de ce type, mais avec l'aide de cette réponse sur le test de directives angulaires personnalisées et quelques expériences, j'ai trouvé un moyen de tester le formulaire à l'unité.
Après avoir installé karma-ng-html2js-preprocessor
et l'avoir configuré, j'ai réussi à obtenir un test unitaire comme celui-ci:
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()
});
Je suppose que je peux ajouter quelques détails à la réponse acceptée: karma-ng-html2js-préprocessor devrait être configuré dans le fichier karma.conf.js de la même manière:
//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"
]
Voici un moyen de tester les unités avec une forme angulaire sans avoir à compiler le modèle d'un contrôleur Fonctionne bien pour moi dans mon utilisation limitée.
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();
});
});
Si vous utilisez WebPack avec karma-webpack
-, vous pouvez également inclure le modèle avec require
, sans avoir besoin du package karma-ng-html2js-preprocessor
:
describe("MyCtrl's form", function () {
var $scope,
MyCtrl;
beforeEach(angular.mock.module("my.module"));
beforeEach(inject(function (_$rootScope_, _$controller_, _$compile_) {
$scope = _$rootScope_.$new();
// Execute the controller's 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>