Javascript 如何将$rootScope注入AngularJS单元测试?

Javascript 如何将$rootScope注入AngularJS单元测试?,javascript,unit-testing,dependency-injection,angularjs,jasmine,Javascript,Unit Testing,Dependency Injection,Angularjs,Jasmine,假设我有一个服务,它依赖于$rootScope中的一个值,与以下(普通)服务一样: 如果我想通过在$rootScope中输入一个值来进行单元测试,那么最好的方法是什么?通过使用provide(),您可以注入一个新的$rootScope: describe('in rootValGetter', inject(function ($rootScope) { var scope; var testRootValGetter; beforeEach(function () {

假设我有一个服务,它依赖于$rootScope中的一个值,与以下(普通)服务一样:

如果我想通过在$rootScope中输入一个值来进行单元测试,那么最好的方法是什么?

通过使用provide(),您可以注入一个新的$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);
    }
}

包括
angular mocks.js
,然后使用:

试着给出一个更详细的答案,包括测试用例:

以下是我所做的:

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

希望这能帮助其他人,因为这是解决类似问题的方法

var rootValGetterService;

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

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

您可以将所需的属性直接模拟到
$rootScope
中,而不是像注入
$scope
时那样创建新的作用域

然后,
$rootScope
将被注入测试代码中可用的属性

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

下面的代码应该适用于您的示例

beforeEach(inject(function($rootScope) {
    $rootScope.specialValue = 'whatever';
}));

这种模式对我不起作用。Angular不断抛出此错误:“错误:注入器已创建,无法注册模块!”为什么需要使用
scope=$rootScope.$new()
,而不是直接使用
$rootScope
?要获得干净的$rootScope,可以尝试从beforeach:
beforeach(inject(函数($rootScope))注入它{
如果你把它放在顶级描述中,有人知道为什么会发生这种情况吗?我花了一段时间反向工作,找出了这个错误的来源。这不是给了你每个测试相同的作用域吗?你如何将新的作用域传递给服务?嗨,Tamlyn,你的根作用域在什么方面不再新鲜了?我相信我只有一次用于广播事件。需要下划线,因为闭包中的
$rootScope
$rootScope
参数之间存在命名冲突。@Tamlyn此参数为每个测试提供了一个新的独立$rootScope。如果有人不喜欢下划线约定,可以在每次(inject)之前这样编写它($injector=>{$rootScope=$injector.get('$rootScope');}))
  it('getVal returns the value from $rootScope', function() {
        var value = 12345;
        $rootScope.specialValue = value;
        expect(testRootValGetterService.getVal()).toBe(value);
    }
it('some kind of wacky test', function($rootScope, Translate){
    $rootScope.lang = 'en';
    expect(Translate('overview').toBe('Overview');
}
var rootValGetterService;

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

it("Should have a service", function () {
    expect(rootValGetterService).toBeDefined();
});
beforeEach(inject(function($rootScope) {
    $rootScope.specialValue = 'whatever';
}));