如何在AngularJS中测试广播事件

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();
});

但结果仍然是负面的。有没有一种方法可以测试事件是否被广播?

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);

@Mike:你能否展示一下使用Mocha/Chai的解决方案的示例? - Ryan Conaway
@RyanConaway - 对于Chai,似乎你需要一个类似于https://github.com/chaijs/chai-spies的监视插件。对于Mocha,请查看http://sinonjs.org/。这两个库的文档都非常清晰地说明了如何使用任一库实现此解决方案。 - Mike Pugh
1
如何测试多次调用不同参数的情况? - BrightIntelDusk
2
@IntegrityFirst - 只需创建更多期望(最好在它们自己的隔离测试中)。 - Mike Pugh
我们如何使用mocha-chai完成相同的操作?我遇到了spyOn未定义的错误。 - Mayank
显示剩余2条评论

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
}))

})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接