I have been learning AngularJS and things have been going pretty smoothly regarding unit testing, but I've reached a bit of a tricky spot.
Suppose I have a simple form, for example:
<form name="form">
<input type="text" name="number" ng-pattern="/^d+$/">
</form>
If I was testing something like a controller, I know that I would write it something like this (using 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();
});
But I don't know which services I need to inject, and I haven't had any luck finding documentation on unit testing in either the forms
guide or the ng-form
documentation.
How does one unit test a form in Angular?
AngularJS is written with testability in mind, but it still requires that you do the right thing. We tried to make the right thing easy, but if you ignore these guidelines you may end up with an untestable application.
Testing in AngularJS is achieved by using the karma framework, a framework which has been developed by Google itself. The karma framework is installed using the node package manager. The key modules which are required to be installed for basic testing are karma, karma-chrome-launcher ,karma-jasmine, and karma-cli.
The angular-cli configuration of karma uses the file “test. ts” as the entry point of the tests for the application.
I'm not convinced this is the best way to unit test something like this but with some help from this answer on testing custom angular directives and some experimentation, I figured out a way to unit test the form.
After installing karma-ng-html2js-preprocessor
and configuring it, I managed to get a working unit test like this:
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()
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With