在angular.js中的karma / jasmine测试中触发输入

时间:2014-09-16 06:20:09

标签: angularjs jasmine karma-runner

我试图在我编写的角度指令中测试更改事件,并且我已经看过人们执行input('text').enter('changed value')等操作的文档,但我一直在收到错误{{ 1}}当我这样做的时候。

在我的指令中,我从一个常规模板开始,它只包含一些文本。 如果用户单击该指令,则span将替换为输入字段,其中模型被设置为作用域的文本(从初始指令元素的文本中检索。

Object doesn't support property or method 'enter'

});

在我的测试中,我有

directive('criInput', function($compile){
return {
    restrict: 'A',
    template: "<span ng-click=\"edit\" ng-transclude></span>",
    transclude: true,
    link: function(scope, elm){

        elm.bind('click', function(){
            scope.text = elm.text();
            setAsInput();
        });

        function setAsInput(){
            elm.html('<input type="text" ng-model="text" ng-change="updateForm()" />');
            $compile(elm.contents())(scope);
        }

        scope.updateForm = function(){
            console.log('form updated', scope.text);
        }   
    }

}

我希望这个测试失败,因为我有意在最初检查错误的值。 有人可以告诉我应该如何测试这个,以便我可以确认文本字段更新触发updateForm函数?

1 个答案:

答案 0 :(得分:0)

你应该在这里尝试几件事。添加&#39;编辑&#39;事件到范围。我不得不说整体而言我对你想要完成什么感到非常困惑,并且当事情发生变化时,比在链接函数内部编译更容易。当您以这种方式替换内容时,您将失去大部分初始跟踪。您可以使用ng-show,然后跟踪单击以分别隐藏/显示范围或输入。祝你好运。

directive('criInput', function($compile) {
        return {
            restrict: 'EA',
            template: '<span ng-click="edit" ng-transclude></span>',
            transclude: true,
            link: function(scope, elm) {

                elm.bind('click', function (event) {
                    scope.edit();
                });

                scope.edit = function() {
                    scope.text = elm.text();
                    console.log('clicked');
                    setAsInput();
                };

                function setAsInput() {
                    elm.html('<input type="text" ng-model="text" ng-change="updateForm()" />');
                    $compile(elm.contents())(scope);
                }

                scope.updateForm = function() {
                    console.log('form updated', scope.text);
                }
            }

        }
    });

然后修改测试以执行类似这样的操作

            var initialText = 'Your wrapped text';
            template = '<span cri-input>' + initialText + '</span>';

            var compiled = $compile(template)($scope);
            $rootScope.$apply();
            console.log(compiled[0]);
            var span = compiled.find('span');
            expect(span.scope().text === 'Terence').toBe(false);
            span.length.should.equal(2);
            span.eq(1).click();
            //you have to find the element since you replaced it
            var input = compiled.find('input');
            expect(input.scope().text === initialText).toBe(true);
            console.log('the text ' + input.scope().text);

            $rootScope.$apply();
            console.log(compiled[0]);