webentwicklung-frage-antwort-db.com.de

Wie kann man die Einheit für den Einheitsprüfungswinkel prüfen?

Ich habe AngularJS gelernt, und beim Unit-Testing lief es ziemlich reibungslos, aber ich habe eine schwierige Stelle erreicht.

Angenommen, ich habe ein einfaches Formular, zum Beispiel:

<form name="form">
    <input type="text" name="number" ng-pattern="/^d+$/">
</form>

Wenn ich so etwas wie einen Controller getestet habe, weiß ich, dass ich so etwas schreiben würde (mit 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();
});

Ich weiß jedoch nicht, welche Dienste ich injizieren muss, und ich hatte kein Glück, in den der forms-Anleitung oder der ng-form-Dokumentation Dokumentation zu Unit-Tests zu finden.

Wie testet eine Einheit ein Formular in Angular?

17
NT3RP

Ich bin nicht überzeugt, dass dies der beste Weg zum Komponententest ist, aber mit etwas Hilfe von dieser Antwort auf das Testen von benutzerdefinierten Winkelanweisungen und einigen Experimenten habe ich einen Weg gefunden, das Formulardetest zu testen.

Nachdem ich karma-ng-html2js-preprocessor installiert und konfiguriert habe, ist es mir gelungen, einen funktionierenden Unit-Test wie folgt zu erhalten:

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()
});
23
NT3RP

Ich denke, ich kann der akzeptierten Antwort einige Details hinzufügen: karma-ng-html2js-preprocessor sollte in der Datei karma.conf.js auf eine ähnliche Weise konfiguriert werden:

//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"
]
4
andrea.spot.

Hier ist eine Möglichkeit, einen Gerätetest mit einer Winkelform auszuführen, ohne die Vorlage eines Controllers erstellen zu müssen. Funktioniert gut für mich in meinem begrenzten Gebrauch.

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();
  });

});
1
ssmith

Wenn Sie WebPack mit karma-webpack - verwenden, können Sie die Vorlage alternativ mit require einfügen, ohne dass karma-ng-html2js-preprocessor-Paket benötigt wird:

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>
1
Jonas Masalskis