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

Этот шаблон не работает для меня. Угловая продолжает метать эту ошибку: «Ошибка: инжектор уже создан, не может зарегистрировать модуль!» – Espilon

+0

Зачем вам нужно использовать 'scope = $ rootScope. $ New();' вместо прямого использования '$ rootScope'? –

+1

Потому что я хочу запускать отдельные тесты, изолированные друг от друга. –

3

Включать angular-mocks.js, а затем использовать angular.mock.inject:

+1

Ссылка на документы устарела, текущая ссылка: https://docs.angularjs.org/api/ngMock/function/angular.mock.inject –

+0

@ GregoryAvery-Weir спасибо! Исправлено. – L42y

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

Не дает ли вам такой же возможности для каждого теста? Как вы передаете новую область обслуживания? – Tamlyn

+0

Привет, Tamlyn, каким образом ваш объем корня больше не свежий? верю, что я использовал его только для трансляции событий. –

+1

Подчеркивания необходимы, потому что в случае замыкания и аргумента '$ rootScope' существует конфликт имен между' $ rootScope'. –

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'; 
})); 
Смежные вопросы