【问题标题】:How do I test $scope.$on in AngularJS如何在 AngularJS 中测试 $scope.$on
【发布时间】:2013-10-26 19:58:16
【问题描述】:

如何测试广播后是否填充了范围?我在 stackexchange 中搜索并找到了一些 QA,但没有一个回答我的问题。代码工作正常,只是不知道如何测试它。我可以补充一点,我是测试新手,尤其是 Jasmine。

所以,这里是代码:

服务 CrappySvc:

update: function() {
    $rootScope.$broadcast('updatecrappy', Crappy.query());
}   

控制器GetCrappyCtrl:

  $scope.$on('updatecrappy', function(event, crap) {
    $scope.crap = crap;
  });

茉莉花:

beforeEach(inject(function($rootScope, $httpBackend, $controller, Crappy) {
  rootScope = $rootScope;
  scope = $rootScope.$new();
  Crappy = mockCrappy;

      ...
  spyOn(rootScope, '$broadcast');
      ...

  ctrl = $controller('GetCrappyCtrl', {
  $scope : scope,
  Crappy : mockCrappy
});               

}));

it('$scope.$on should have been triggered', function() {          
  rootScope.$broadcast('updatecrappy', [{id : 2, name : 'crappy'}]);
  expect(rootScope.$broadcast).toHaveBeenCalledWith('updscenes', [{id : 2, name : 'crappy'}]);

});

石头

【问题讨论】:

标签: unit-testing angularjs jasmine angularjs-scope


【解决方案1】:

你需要告诉 Jasmine 让间谍调用实际的 $broadcast 函数

spyOn($rootScope, '$broadcast').andCallThrough();

如果你不使用andCallThrough(),间谍什么都不做。

Jasmine Docs

编辑

对于 Jasmine 2,语法是

spyOn($rootScope, '$broadcast').and.callThrough();

【讨论】:

  • 我们能否详细说明这实际上在做什么?
  • @whitebox 就是这样,它并没有真正做太多。默认情况下,Jasmine 的间谍将替换被监视的原始功能。调用and.callThrough() 将添加到默认行为并导致间谍调用被窥探的原始函数。这就是它所做的一切。
  • 如果你只是断言广播被调用,那么在这种情况下你不需要 and.callThrough()
  • mocha 有没有类似 .callThrough 的东西
  • 据我所知,mocha 没有自己的间谍功能,因此这取决于您用于模拟的库。
【解决方案2】:

如果想从$scope.$broadcast() 伪造returnValue,您可以执行以下两种情况:

案例一:

scope.$broadcast('TEST_CHANGED', {test: 'test1'});
spyOn(scope, '$broadcast').and.callThrough();
expect(something).toEqual('something');

案例 2:

scope.$broadcast('TEST_CHANGED', {test: 'test2'});
spyOn(scope, '$broadcast').and.callThrough();
expect(something2).toEqual('something2');

【讨论】:

    【解决方案3】:

    就“toHavebeenCalled”而言,不需要“andCallThrough()”。简单的间谍就可以了。在你的情况下,你的论点是不同的。

    你正在广播, rootScope.$broadcast('updatecrappy', [{id : 2, name : 'crappy'}]);

    但你期望:

    expect(rootScope.$broadcast).toHaveBeenCalledWith('updscenes', [{id : 2, name : 'crappy'}]);

    查看参数“updarecrappy”,但实际上它被称为“updscenes”。

    【讨论】:

      【解决方案4】:

      看看下面的示例代码,它对我很有效。

      从 $rootScope 发出示例事件“onTimeChanged”。我的控制器有一个监听器“onTimeChanged”,我在其中调用了一个方法 timeChanged()。

      describe('onTimeChanged()', function() {
          it('should call another method or controller', function() {
              spyOn(searchCtrl, 'timeChanged');
              $rootScope.$emit('onTimeChanged');
              expect(searchCtrl.timeChanged).toHaveBeenCalled();
          });
      });
      

      请注意,我没有监视 rootScope 的方法“$emit”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-14
        • 2016-02-14
        • 1970-01-01
        • 1970-01-01
        • 2014-09-30
        相关资源
        最近更新 更多