spyOn $ scope.$ on on broadcast toHaveBeenCalled失败

Ben*_*Ben 3 events unit-testing jasmine angularjs angularjs-scope

这个简单的测试工作我遇到了很多麻烦.

$scope.$on在控制器中有一个我想测试的监听器.我只是想确定它是在广播事件之后调用的.

为此,我认为以下代码可行:

describe("Testing the parent controller: ", function() {
    var scope, ctrl;

    beforeEach(function() {
        module("myApp");

        inject(function($rootScope, $controller) {
            scope = $rootScope.$new();

            ctrl = $controller('parent-ctrl', {
                $scope: scope,
            });
        });
    });


    it ("should trigger broadcast when current page updates", function() {
        spyOn(scope, "$on");
        scope.$broadcast("myEvent", 999);
        expect(scope.$on).toHaveBeenCalled();
    });
});
Run Code Online (Sandbox Code Playgroud)

它没有(Expected spy $on to have been called.).我挖过很多例子:

并且学到了很多,但由于某种原因,我只是没有做出一些关键的联系.

我注意到$on处理程序确实响应后断言,这是无益的.我试着scope.$apply().andCallThrough()各种配置,但似乎没有任何工作.

这是怎么做到的?

tas*_*ATT 8

当广播事件时$on,执行的是注册的侦听器功能,而不是$on功能本身.

您当前的测试适用于这样的代码,这可能不是您拥有的:

$scope.$on('myEvent', function () {
    $scope.$on('whatever', someFn);
});
Run Code Online (Sandbox Code Playgroud)

你应该测试的是你注册的监听器功能正在做什么.

所以如果你有例如:

$scope.$on('myEvent', function() {
  myFactory.doSomething();
});
Run Code Online (Sandbox Code Playgroud)

像这样测试:

spyOn(myFactory, "doSomething");
scope.$broadcast("myEvent");

expect(myFactory.doSomething).toHaveBeenCalled();
Run Code Online (Sandbox Code Playgroud)