12

假设我有一个依赖于$ rootScope的值,如通过以下(简单)服务的服务:

angular.module('myServices', []) 
.factory('rootValGetterService', function($rootScope) { 
    return { 
     getVal: function() { 
      return $rootScope.specialValue; 
     } 
    }; 
}); 

如果我想单元测试这种通过把一个价值$ rootScope,什么是最好的方式去了解它?

回答

6

通过使用提供(),你可以注入新的$ rootScope:

describe('in rootValGetter', inject(function ($rootScope) { 
    var scope; 
    var testRootValGetter; 

    beforeEach(function() { 

     scope = $rootScope.$new(); 

     module(function ($provide) { 
      $provide.value('$rootScope', scope); 
     }); 

     inject(function ($injector) { 
      testRootValGetterService = $injector.get('rootValGetterService'); 
     }); 
    }); 

    it('getVal returns the value from $rootScope', function() { 
     var value = 12345; 

     scope.specialValue = value; 

     expect(testRootValGetterService.getVal()).toBe(value); 
    } 
} 
+12

此模式不适用于我。 Angular一直抛出这个错误:“错误:注射器已经创建,无法注册模块!” – Espilon 2013-07-10 16:16:16

+0

为什么你需要使用'scope = $ rootScope。$ new();',而不是直接使用'$ rootScope'? – 2014-01-02 22:06:11

+1

因为我想运行相互隔离的单元测试。 – 2014-01-03 03:05:19

3

包括angular-mocks.js,然后使用angular.mock.inject

+1

到文档的链接已过时;当前链接是:https://docs.angularjs.org/api/ngMock/function/angular.mock.inject – 2014-08-11 20:53:55

+0

@ GregoryAvery-Weir谢谢!更正。 – L42y 2014-08-12 22:18:53

21
... 
var $rootScope; 
beforeEach(inject(function(_$rootScope_) { 
    $rootScope = _$rootScope_; 
})); 
... 
+0

这不是每个测试都给你同样的范围吗?你如何将新的范围传递给服务? – Tamlyn 2015-06-05 14:46:34

+0

嗨Tamlyn,你的根范围不再是新鲜的?相信我只用它来广播事件 – 2015-06-08 13:37:07

+1

下划线是需要的,因为在闭包中的$ rootScope和'$ rootScope'参数之间存在命名冲突。 – 2015-06-16 03:13:28

0

只是试图给出更详细的解答,包括测试案例:

...

var $rootScope; 
beforeEach(inject(function(_$rootScope_) { 
    $rootScope = _$rootScope_; 
})); 

...

it('getVal returns the value from $rootScope', function() { 
     var value = 12345; 
     $rootScope.specialValue = value; 
     expect(testRootValGetterService.getVal()).toBe(value); 
    } 
0

这里就是我所做的:

it('some kind of wacky test', function($rootScope, Translate){ 
    $rootScope.lang = 'en'; 
    expect(Translate('overview').toBe('Overview'); 
} 
0

希望这会帮助别人,因为这是解决类似的问题。

var rootValGetterService; 

beforeEach(inject(function($rootScope,$injector) { 
    $rootScope.specialValue = "test"; 
    rootValGetterService= $injector.get('rootValGetterService'); 
})); 

it("Should have a service", function() { 
    expect(rootValGetterService).toBeDefined(); 
}); 
0

不是创建一个新的范围,你会如果你注入$scope你可以嘲笑性质的需要直接插入$rootScope

然后$rootScope将注入您正在测试的代码中提供的那些属性。

至少这是我解决同样问题的方式。

下面的代码应该在你的例子中工作。

beforeEach(inject(function($rootScope) { 
    $rootScope.specialValue = 'whatever'; 
})); 
相关问题