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 $scopes 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