使用ngModel的AngularJS单元测试指令

时间:2014-08-15 16:11:18

标签: angularjs unit-testing angularjs-directive

我做了一个使用ngModel的指令:

.directive('datetimepicker', function () {
    return {
        restrict: 'E',
        require: ['datetimepicker', '?^ngModel'],
        controller: 'DateTimePickerController',
        replace: true,

        templateUrl: ...,

        scope: {
            model: '=ngModel'
        },

        link: function (scope, element, attributes, controllers) {
            var pickerController = controllers[0];
            var modelController = controllers[1];

            if (modelController) {
                pickerController.init(modelController);
            }
        }
    }
});

但是在测试时......

var scope, element;

beforeEach(module('appDateTimePicker'));
beforeEach(module('templates'));

beforeEach(inject(function ($compile, $rootScope) {
    compile = $compile;
    scope = $rootScope;

    scope.model = new Date();

    element = compile(angular.element('<datetimepicker ng-model="model"></datetimepicker>'))(scope);

    scope.$digest();
}));

我无论如何都不能为ng-model设定价值。

例如,此处scope.model是一个日期,因此scope.year和scope.month应该是该模型的日期和年份,但它未定义。

如指令代码所示,我在控制器上使用this.init来初始化所有过程。

我错过了什么?

修改

测试示例:

it('should test', function () {
    expect(scope.model).toBe(undefined);
    expect(scope.year).toBe(undefined);
});

修改

这有助于解决问题:http://jsfiddle.net/pTv49/3/

2 个答案:

答案 0 :(得分:3)

'?^ngModel'表示您要求父元素上的ng-model,但测试中的html与ng-model指令在同一元素上的datetimepicker。< / p>

如果ng-model确实必须在父元素上,则必须更改测试中的html,例如:

element = compile(angular.element('<div ng-model="model"><datetimepicker></datetimepicker></div>'))(scope);

但如果它应该在同一个元素上,只需删除^

中的require:符号
require: ['datetimepicker', '?ngModel'],

答案 1 :(得分:0)

该指令具有scope: {}块,因此它创建了一个隔离范围。我假设,在测试scope中引用了外部范围,而element.isolateScope()应该用来引用内部范围。