2013-04-15 89 views
7

我一直在试图测试服务无济于事了一段时间,希望得到一些帮助。这里是我的情况:AngularJS注入服务模拟内服务测试

我有一个服务看起来有点像这样

myModule.factory('myService', ['$rootScope', '$routeParams', '$location', function($rootScope, $routeParams, $location) { 

    var mySvc = { 
    params: {} 
    } 

    // Listen to route changes. 
    $rootScope.$on('$routeUpdate', mySvc.updateHandler); 

    // Update @params when route changes 
    mySvc.updateHandler = function(){ ... }; 

    ... 
    ... 

    return mySvc; 

}]); 

我想嘲笑服务之前注入'myService'服务被注入到我的测试,所以我可以测试初始化代码下面

var mySvc = { 
    params: {} 
    } 

    // Listen to route changes. 
    $rootScope.$on('$routeUpdate', mySvc.updateHandler); 

我使用茉莉花为测试和模拟。这是我现在想出的

describe('myService', function(){ 
    var rootScope, target; 
    beforeEach(function(){ 
    rootScope = jasmine.createSpyObj('rootScope', ['$on']); 

    module('myModule'); 
    angular.module('Mocks', []).service('$rootScope', rootScope); 
    inject(function(myService){ 
     target = myService; 
    });   
    }); 

    it('should be defined', function(){ 
    expect(target).toBeDefined(); 
    }); 

    it('should have an empty list of params', function(){ 
    expect(target.params).toEqual({}); 
    }); 

    it('should have called rootScope.$on', function(){ 
    expect(rootScope.$on).toHaveBeenCalled(); 
    }); 
}); 

虽然这不起作用。我的rootcope模拟不是取代原来的,而且依赖注入文档使我更加困惑。

请帮

回答

7

我想窥探,而不是试图注入自己的自定义对象的实际$ rootScope。

var target, rootScope; 
beforeEach(inject(function($rootScope) { 
    rootScope = $rootScope; 

    // Mock everything here 
    spyOn(rootScope, "$on") 
})); 

beforeEach(inject(function(myService) { 
    target = myService; 
})); 

it('should have called rootScope.$on', function(){ 
    expect(rootScope.$on).toHaveBeenCalled(); 
}); 

我已经在CoffeScript中测试过了,但上面的代码仍然可以工作。

+0

非常感谢!像魅力一样工作。我不相信我以前没有尝试过。 –

+0

我必须将 spyOn(rootScope,“$ on”)添加到 spyOn(rootScope,“$ on”)和.CallThrough(); 但工作很好,让我朝着正确的方向前进。 – blackmind

0

您可以创建一个RootController,然后注入其:

inject(function(myService, $controller){ 
    target = myService; 
    $controller('rootController', { 
     $scope : $rootScope.$new(), 
     $rootScope : myService 
    }); 
}); 

通过这种方法,你可以从你的“为myService”访问$ rootScope功能; 这样的'myService。$ on()'

我刚刚提出,让我知道是否需要帮助。