0

问题:
- 使用 AngularJs
- 给定一个实现的服务
- 尝试用 Jasmine 测试它

这是我的服务的样子:

angular.module('app.common').service('StateInterceptor',['$state','$rootScope',function($state,$rootScope){
    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){/*stuffs*/}

}

这就是我试图测试是否$rootScope.$on已被调用的方法:

describe("Testing StateInterceptor service", function(){
var $state, $rootScope, $scope, StateInterceptor;

beforeEach(module('app.common'));

beforeEach(inject(function($injector) {
    $rootScope = $injector.get("$rootScope");
    spyOn($rootScope, "$on");

    $state = $injector.get("$state");

    StateInterceptor = $injector.get("StateInterceptor");
}));

it("WHEN created THEN it should call '$rootScope.$on' event listener", function(){
    //expect($rootScope.$on).toHaveBeenCalled(); //not working neither
    expect($rootScope.$on).toHaveBeenCalledWith("$stateChangeStart", jasmine.any(Function));
});

我得到的是一条错误消息,说:

预计 spy $on 会被调用...(blabla),但它从未被调用过。

我已经尝试了几乎所有类似的方法: - 在此创建 rootscope 是:$rootScope = $rootScope.$new(); -$rootScope.$on以这种方式进行间谍活动:spyOn($rootScope.prototype, "$on")

但两者都没有工作。有人知道如何以正确的方式测试它吗?

编辑1:

原始代码似乎可以正常工作,所以我在这里粘贴了我拥有的确切代码。所以我的服务看起来就像这样:

angular.module('app.common').service('StateInterceptor',['$state','$rootScope',function($state,$rootScope){
    var self = this;
    self.bootstrapped = false;
    self.changeStart = [];


    self.init = function(){
        if(!self.bootstrapped){
            $rootScope.$on('$stateChangeStart',
                function(event, toState, toParams, fromState, fromParams){
                /*staffs*/
                }
            );
        }
    }
    self.bootstrapped = true;

    self.init();
    return self;
}]);

编辑2:

我放了一些 console.log 来看看代码是如何执行的:

beforeEach(inject(function($injector) {
    $rootScope = $injector.get("$rootScope");
    spyOn($rootScope, "$on");

    $state = $injector.get("$state");

    StateInterceptor = $injector.get("StateInterceptor");
}));

对于 self.init 函数中第一行的代码:

console.log("init runs");

结果是: 'init runs' 'before' 'after'

奇怪的!知道为什么吗?

4

2 回答 2

0

尝试为“$stateChangeStart”事件调用 $broadcast,它应该会自动进入 $on()。

于 2014-12-29T11:09:26.337 回答
0

首先,非常感谢tasseKATT帮助我。他是带领我找到解决方案的人。

问题是我在这个模块中有另一个函数,当我用'beforeEach(module(“app.common”))'将模块注入我的测试套件时立即运行。

这是另一个函数的样子:

angular.module('app.common').run(function($q,StateInterceptor,$modal){
  //stuffs, but pls notice that it injects the StateInterceptor which caused the problem!
});

所以我把它放到另一个模块中,并使其成为另一个模块的依赖项。

于 2014-12-29T12:18:51.747 回答