How do I inject $rootScope into an AngularJS unit test?
Solution 1
...
var $rootScope;
beforeEach(inject(function(_$rootScope_) {
$rootScope = _$rootScope_;
}));
...
Solution 2
By using provide(), you can inject a new $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);
}
}
Solution 3
Include angular-mocks.js
, then use angular.mock.inject
:
Solution 4
Instead of creating a new scope as you would if you were injecting $scope
you can mock the properties you need directly into $rootScope
.
Then $rootScope
will be injected with those properties available in the code you are testing.
At least this is the way I solved the same problem.
The following code should work in your example.
beforeEach(inject(function($rootScope) {
$rootScope.specialValue = 'whatever';
}));
Gregory Avery-Weir
I'm a game developer specializing in story-focused games. I made "The Majesty of Colors" and "How to Raise a Dragon." I'm co-founder of Future Proof Games. We've released the dialogue-based pixel-horror satire Ossuary and are currently in alpha on the social cyberpunk puzzle game Exploit: Zero Day.
Updated on April 26, 2020Comments
-
Gregory Avery-Weir about 4 years
Suppose I have a service that depends on a value in $rootScope, as with the following (trivial) service:
angular.module('myServices', []) .factory('rootValGetterService', function($rootScope) { return { getVal: function () { return $rootScope.specialValue; } }; });
If I want to unit test this by putting a value in $rootScope, what is the best way to go about it?
-
Chris Esplin almost 11 yearsThis pattern is not working for me. Angular keeps throwing this error: "Error: Injector already created, can not register a module!"
-
Tom Söderlund over 10 yearsWhy do you need to use
scope = $rootScope.$new();
, instead of using$rootScope
directly? -
gentooboontoo almost 10 yearsTo have a clean $rootScope, you could try to inject it from beforeEach:
beforeEach(inject(function($rootScope) {
-
Tamlyn almost 9 yearsDoesn't this give you the same scope for every test? How do you pass a fresh new scope to the service?
-
Markus Coetzee almost 9 yearsHi Tamlyn, in what way is your root scope no longer fresh? I believe I've only ever used it to broadcast events.
-
Bart Verkoeijen almost 9 yearsThe underscores are needed because there is otherwise a naming conflict between the
$rootScope
in the closure and$rootScope
argument. -
temporary_user_name over 8 yearsDoes anyone know why this happens if you put it on the top-level describe? Took awhile working backwards to figure out where I was getting this error from.
-
katsos about 7 years@Tamlyn this one gives a new isolated $rootScope to each test. If anyone doesn't like the underscore convention can write it like this
beforeEach(inject($injector => { $rootScope = $injector.get('$rootScope'); }))