单元测试Angular指令表达式属性,它传递promises

时间:2016-08-11 18:12:54

标签: javascript angularjs unit-testing jasmine

我花了很多时间尝试对一个指令进行单元测试,该指令在控制器中生成/跟踪一个承诺,这里可以看到如何实现这一点的示例:https://plnkr.co/edit/d8wMq0qlpiE4P25q5lhB

指令:

.directive('testDirective', function() {
    return {
        scope: {
            save: '&',
        },
        template: '<div><a href="#" ng-click="handleSave($event)">Click Here</a></div>',
        link: function(scope, element, attr, controllers) {

            scope.someData = {
                saving: false
            };

            scope.handleSave = function() {
                scope.someData.name = parseInt(Math.random() * 100);
                scope.someData.saving = true;
                scope.someData.error = false;
                scope.someData.id = null;
                return scope.save()(scope.someData)
                    .then(function(data) {
                        scope.someData = data;
                    })
                    .catch(function(err) {
                        scope.someData.error = true;
                    })
                    .finally(function() {
                        scope.someData.saving = false;
                    });
            };

        }
    };
})

控制器:

.controller('TestCtrl', function($scope, $q, $timeout) {
    $scope.saveCtrl = function(directiveData) {
        return $q(function(resolve, reject) {
            $timeout(function() {
                if (Math.round(Math.random())) {
                    directiveData.id = parseInt(Math.random() * 100);
                    resolve(directiveData);
                } else {
                    reject(new Error());
                }
            }, 2000)
        });
    }
});

模板:

<test-directive save="saveCtrl"></test-directive>

它作为一个组件起作用,如示例中所示,但测试无法完成,因为.finally()永远不会被调用。我已经尝试了很多变化来强制$ digest,但似乎没有任何东西可以完成承诺。

1 个答案:

答案 0 :(得分:0)

想想我明白了。 https://plnkr.co/edit/CBvrZo4g9LjJC61VV0wp

```

$scope.saveCtrl = function(data) {
    return $q(function(resolve, reject) {
        setTimeout(function() {
            if (Math.round(Math.random())) {
                var id = parseInt(Math.random() * 100);
                resolve(id);
            } else {
                reject(new Error());
            }
            elementScope.$apply();
            $scope.$apply();
        }, 100);
   });
};

```

第39行有一个未定义的var,角度超时表现得很奇怪。这应该导致指令的完整流程保存以使用超时进行测试。我认为可能不需要超时,因为您可以假设即时超时情况而不会丢失任何测试。