How to unit test angularjs form?

前端 未结 4 1600
长情又很酷
长情又很酷 2020-12-13 10:41

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 f

相关标签:
4条回答
  • 2020-12-13 11:04

    I guess i can add some details to the accepted answer: karma-ng-html2js-preprocessor should be configured in the karma.conf.js file in a similar way:

    //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"
    ]
    
    0 讨论(0)
  • 2020-12-13 11:04

    Here's a way to unit test with an angular form without having to compile a controller's template. Works well for me in my limited usage.

    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();
      });
    
    });
    
    0 讨论(0)
  • 2020-12-13 11:06

    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()
    });
    
    0 讨论(0)
  • 2020-12-13 11:17

    Alternatively, if you are using WebPack with karma-webpack - you can include the template with require, without the need of karma-ng-html2js-preprocessor package:

    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>
    
    0 讨论(0)
提交回复
热议问题