Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Jasmine、AngularJs测试uu.defer()_Angularjs_Unit Testing_Jasmine_Underscore.js - Fatal编程技术网

如何使用Jasmine、AngularJs测试uu.defer()

如何使用Jasmine、AngularJs测试uu.defer(),angularjs,unit-testing,jasmine,underscore.js,Angularjs,Unit Testing,Jasmine,Underscore.js,我已经问过这个问题,重点是范围在终端中不存在,但它存在于Chrome调试工具中。尽管有答案,它还是没有得到修复 问题是测试bellow指令的正确语法是什么,尤其是行expect(scope.measurementScroll).toBe(true)。在浏览网页时,我找不到任何类似的问题,大多数问题都与$q.defer()有关,在我的例子中,这里有下划线方法\uu.defer() 控制器 'use strict'; angular.module('myApp') .controller('Me

我已经问过这个问题,重点是范围在终端中不存在,但它存在于Chrome调试工具中。尽管有答案,它还是没有得到修复

问题是测试bellow指令的正确语法是什么,尤其是行
expect(scope.measurementScroll).toBe(true)。在浏览网页时,我找不到任何类似的问题,大多数问题都与
$q.defer()
有关,在我的例子中,这里有下划线方法
\uu.defer()

控制器

'use strict';
angular.module('myApp')
  .controller('MeasurementsTimelineCtrl', ['$scope', '$state', 'Measurements', function($scope, $state, Measurements) {
    $scope.measurements = null;
    var userId = $scope.currentUser ? $scope.currentUser.id : null;
    if (userId) {
      var listOfMeasurements = Measurements.userIndex(userId);
      listOfMeasurements.then(function(data){
        $scope.measurements = data;
        $scope.$broadcast('measurements-updated', $scope.measurements);
      });
    }
  }]);
指令:

'use strict';
angular.module('myApp')
  .directive('dashboardMeasurementTimeline', ['$window', function($window) {
    return {
      restrict: 'E',
      templateUrl: 'myView.html',
      controller: 'MeasurementsTimelineCtrl',
      link: function(scope, element){
        scope.$on('measurements-updated', function(measurements) {
          _.defer(function(){
            if(measurements) {
              scope.measurementScroll = true;
            }
          });
        });
      }
    };
  }]);
试验

“严格使用”;
描述('指令:仪表板度量TTIMELINE',函数(){
var$rootScope,$compile,element,scope;
beforeach(函数(){
模块(“myApp”);
注入(函数($injector){
$rootScope=$injector.get(“$rootScope”);
$compile=$injector.get(“$compile”);
});
scope=$rootScope.$new();
元素=角度。元素(“”);
元素=$compile(元素)(范围);
scope.currentUser={id:'someId'};
范围。$digest();
scope.measurements=[{id:'someId',测试时间:'Tue,2014年12月30日14:00:00-0000'},
{id:'someId',测试时间:'Thu,2014年11月20日03:00:00-0000'},];
范围:$broadcast('measurements-updated',scope.measurements);
作用域:$apply();
});
它('应该为measurementScroll'分配真值',函数(){
expect(scope.measurementScroll).toBe(true);
});
});

您可以通过注入模拟下划线库来实现这一点,该库带有测试中定义的
defer
函数。实现这一点的一种方法是定义自己的工厂,
\uu
,然后可以很容易地对其进行模拟:

app.factory('_', function($window) {
  return $window._;
});
然后在指令中,您必须通过注入来使用它:

app.directive('dashboardMeasurementTimeline', ['_', function(_) {
在测试中,您可以模拟它:

var deferCallback;
beforeEach(module(function($provide) {
  deferCallback = null;
  $provide.value('_', {
    defer: function(callback) {
      deferCallback = callback;
    }
  });
}));
这意味着指令将使用mock
\uuu
,而不是真实的,它将传递给
defer
的回调保存为
deferCallback
,以便您可以在需要时调用它:

scope.$broadcast('measurements-updated', scope.measurements);
deferCallback();
这使得测试同步,这通常比使用
done()


您可以在

@Michal Charezma上看到上面的内容,它为这个问题提供了一个很好的解决方案,实际上它是一个解决方案,但事实证明它对其余的
函数有一些其他限制。 例如:

angular.element(scrollContainer).bind('scroll', _.throttle(scope.disableButtons, 500));
引发一个错误,
油门未定义

按照@Michal的逻辑,我们找到了另一个解决方案,可以让
..throttle()
这样的函数正常工作。因此,与其导入
\uuuu
并使用:

app.factory('_', function($window) {
  return $window._;
});
可以仅从规范中模拟
defer
函数,如:

var deferCallback = $window._.defer.mostRecentCall.args[0];
deferCallback()

如果您没有lodash作为要注入的服务,您只需监视
defer
方法,如果您关心传递的函数的执行,那么您只需设置
callFake
并调用传递给real
defer
的参数函数:

spyOn(_, 'defer').and.callFake(f => f());
更深入地说,假设您有以下电话:

function toTest() {
 _.defer(() => service.callAFunction());
}
然后在测试中,你可以说:

it('should call service.callAFunction', () => {
   spyOn(service, 'callAFunction');
   spyOn(_, 'defer').and.callFake(f => f());
   toTest();
   expect(_.defer).toHaveBeenCalled();
   expect(service.callAFunction).toHaveBeenCalled();
}

我使用的插件是
karma jasmine:0.1.5
,而谷歌发现它相当于jasmine 2.0非常感谢亲爱的@Michal Charezma,你的解决方案很棒,解决了这个问题。我现在有一个小问题,那就是在模拟
\uu
并将其导入指令之后,当使用
.
的其他方法时,它会引发一个错误,例如我正在使用:
angular.element(scrollContainer.bind('scroll',u.throttle(scope.disableButtons,500))
方法
throttle()
似乎没有exist@Max您应该能够将
throttle
添加到传递给
$provide.value
的对象中。我认为此方法实际上不会生成模拟对象。我怀疑这甚至可能导致回调延迟执行两次,一次是强制执行的,另一次是在延迟调用初始化超时后执行的。哦,这真的很有趣,我必须再次检查规范。多谢各位。)
it('should call service.callAFunction', () => {
   spyOn(service, 'callAFunction');
   spyOn(_, 'defer').and.callFake(f => f());
   toTest();
   expect(_.defer).toHaveBeenCalled();
   expect(service.callAFunction).toHaveBeenCalled();
}