在Angular服务中测试事件侦听器的输出

时间:2013-11-21 07:26:12

标签: angularjs jasmine

这是一个让我好几天的问题。带有代码示例的Plunkr在这里:http://plnkr.co/edit/QHJCyKfM2yFyCQzB68GS?p=preview

基本上,我有一个正在侦听事件并返回值的服务工厂。

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.$on("myEvent", function(args, value) {
    $scope.myEventCalled = true;
  });
});

app.factory('myService', function($rootScope){
  var mysvc = {}
  mysvc.testVar = true
  $rootScope.$on('otherEvent', function(args, value){
    $rootScope.rootCalled = true;
    mysvc.testVar = false;
  });
  return mysvc

});

我的测试是:

describe('Testing a Hello World controller', function() {
  var $scope = null;
  var svc = null

  //you need to indicate your module in a test
  beforeEach(module('plunker'));

  it('should be able to see settings in service', inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();

    inject(function($httpBackend, myService) {
      svc = myService
    })

    expect(svc).toBeDefined();
    expect(svc.testVar).toBe(true);
  }));

  it('should invoke otherEvent when  "otherEvent" broadcasted in service', inject(function($rootScope, $controller) {
    $scope = $rootScope.$new();

    inject(function($httpBackend, myService) {
      svc = myService
    })

    $scope.$broadcast('otherEvent');
    expect(svc.testVar).toBe(false);
  }));
});

第一次测试通过,但第二次测试失败,因为它无法触发事件并访问修改后的值。

我知道如何使用控制器对此进行测试,但验证该值已从服务中更改已经逃脱了我。我会很感激任何建议。

1 个答案:

答案 0 :(得分:1)

myService正在聆听$rootScope,但在第二次测试中,该事件已在$scope上播出。由于$broadcast将事件名称向下发送到所有子范围及其子级,因此不会达到$rootScope

在第二次测试中将其更改为此,它将起作用:

$rootScope.$broadcast('otherEvent');

但是,在测试控制器时,建议使用其依赖项的模拟版本,并仅隔离测试控制器自身的功能。以同样的方式,每项服务都应该有自己的规范。