2016-08-11 36 views
1

我花了一大堆時間試圖單元測試一個指令,該指令在控制器內生成/跟蹤一個承諾,這是如何完成的一個例子可以在這裏看到: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()永遠不會被調用。我已經嘗試了很多變化來強制$摘要,但似乎沒有完成承諾。

+0

我是一個角度n00b,有沒有辦法將一個指令注入測試並直接調用'link'方法,或者你是否需要編譯和消化它來評估它? – dm03514

+0

爲最小可行的測試,是否有可能從'saveCtrl'中刪除$超時,所以承諾立即解決?並通過不使用隨機的??從測試中消除非確定性。理想情況下,可以有2個單獨的測試,一個「拒絕」分支和一個「分支」分支? – dm03514

+0

@ dm03514當然,我將它添加到實際指令中的功能以重新創建異步調用,您可以完全刪除超時並立即解決/拒絕。調用'link'方法的唯一好方法就是通過這些編譯的指令,但是你總是可以將可測試的功能分割成單獨的'controller'。 – spaceribs

回答

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和角超時被奇怪行爲。這應該導致指令的完整流程在超時時間內進行測試。我認爲可能不需要超時,因爲您可以假設即時超時情況而不會丟失任何測試。

+0

醫管局,我從來沒有猜到爲模擬的承諾增加額外的摘要,瘋了! – spaceribs