63

我有一个在 rootscope 上发出广播事件的控制器。我想测试一下广播事件是否正确触发。

我的控制器中的代码如下所示:

   $scope.$watch("pageIndex", function(){
    if($scope.pageIndex == 4)
    {
      // emit social share
      $rootScope.$broadcast('myEvent');
    }
  });

我尝试使用以下代码对其进行测试:

    it('Should call myEvent when pageIndex is 4',function(){
    scope.pageIndex = 4;
    scope.$apply();
    expect(rootScope.$on).toHaveBeenCalledWith('myEvent');
});

但它告诉我没有调用代码,我已经手动测试了它。然后我尝试了以下代码:

it('Should call myEvent when pageIndex is 4',function(){
    var listener = jasmine.createSpy('listener');
    rootScope.$on('myEvent', listener);
    scope.pageIndex = 4;
    scope.$apply();
    expect(listener).toHaveBeenCalled();
});

但同样的负面结果。有没有办法测试事件是否被广播?

4

2 回答 2

117

假设您使用的是 Jasmine,以下对我来说非常有用。

... other unit test setup code ...

var rootScope;
beforeEach(inject(function($injector) {
    rootScope = $injector.get('$rootScope');
    spyOn(rootScope, '$broadcast');
}));

describe("my tests", function() {
    it("should broadcast something", function() {
        expect(rootScope.$broadcast).toHaveBeenCalledWith('myEvent');
    });
});

如果您正在广播一条消息并将对象附加到它,您甚至可以测试这些对象是否符合预期

someObj = { ... something ... };
expect(rootScope.$broadcast).toHaveBeenCalledWith('someEvent', someObj);
于 2013-06-21T03:30:34.057 回答
12

以下是使用 mochaJs 完成的方法,使用 sinon 进行模拟,使用 chai 进行期望。

describe("broadcast test", function() {
  beforeEach(inject(function($rootScope){
   sinon.spy($rootScope, "$broadcast")
   scope.foo() //this broadcasts the event. $rootScope.$broadcast("testEvent")
 }))

it("broadcasts the event", inject(function($rootScope){
 expect($rootScope.$broadcast.calledWith("testEvent")).to.be.true
}))

})
于 2016-01-13T16:33:43.363 回答