I use a basic pattern in my unit tests (running with karma/jasmine) for my angular components and I do not manage to establish if my solution is safer or overkill than the one suggested by my coworkers:
TL;DR: What are the pros/cons of working with $rootScope directly in unit tests (only!)?
Here's my current pattern:
describe('component', function() {
var $scope;
beforeEach(module('myModule'));
beforeEach(inject(function($rootScope) {
$scope = $rootScope.$new();
//working with it now
$scope.foo = 'fooValue';
$scope.$digest();
}));
afterEach(function() {
$scope.$destroy();
});
describe('subcomponent', function() {
it('should do something', function() {
//arrange
//act
//assert
});
});
});
And my coworkers suggest that using:
$scope = $rootScope;
instead of
$scope = $rootScope.$new();
would be simpler with no side-effect since inject
creates a new $injector
before each spec which provides a new and clean$rootScope
.
So, what could be the benefits / risks of these two solutions?
Nota bene: In our apps, we always avoid using $rootScope
directly.
Testing directly on the $rootScope
should work just fine in most cases. However, if the component that you are testing injects $rootScope
then the following weirdness happens:
element.scope() === $rootScope
$scope === $rootScope
(The above is true assuming you don't mock $rootScope
). Always instantiating a child scope via $rootScope.$new()
as you've been doing is a safety measure which costs little to implement.
Also keep in mind that $rootScope
and $rootScope.$new()
are not instances of the same class, although in practice this hardly seems to be an issue in unit testing...
$rootScope
object:$rootScope.$new()
:$rootScope.$new(true)
:I suspect there isn't much in it. The only practical difference between the $rootScope
and child $scope
s that I know of, is that $parent
is null
on $rootScope
. Using $parent
can be quite brittle, and so I wouldn't recommend it.
So as a first port of call, I would use
$scope = $rootScope;
If your component depends on $parent
being not null, the test should fail, and you can decide whether to change the test to use
$scope = $rootScope.$new();
or change the component to not depend on $parent
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With