Unit testing a run(..)
block is as simple as loading your module(..)
in jasmine.
All of the code below is available in this plunker.
Consider the following very simple app.js:
var _idx = 1;
window.log = function(s) {
console.log('(' + _idx++ + ') ' + s);
};
var app = angular.module('myapp', []);
app.run(function($rootScope) {
log('run block');
$rootScope.valueSetInRun = 666;
});
app.controller('MainCtrl', function($scope) {
log('MainCtrl block');
});
Note that the markup is irrelevant in this app.
Now consider the following test:
describe('myapp', function() {
beforeEach(module('myapp'));
beforeEach(inject(function($rootScope) {
log('beforeEach');
}));
it('should allow me to test the run() block', inject(function ($rootScope) {
log('it block');
expect( $rootScope.valueSetInRun ).toBe(666);
}));
});
Here is the console output:
(1) run block
(2) MainCtrl block
(3) run block
(4) beforeEach
(5) it block
Note that the test passes
Some important observations
- The first two console outputs,
(1)
and (2)
are logged during normal app execution
- Log messages
(3)
to (5)
are outputted while the test is running.
Given the above, we can conclude the following:
- In the unit test, the module 'myapp' was instantiated
- In the unit test, MainCtrl wasn't instantiated
- In the unit test, the
run
block was executed
- When running a unit test, the
beforeEach...run
block is executed first, then beforeEach
and finally the it
block.
- The second
beforeEach
is not useful for unit testing a run
block (note that you can put a beforeEach
block before beforeEach(module('myapp'));
, however if you try creating an injector in that block your test will fail)
And finally, we can conclude that the code above is how you can test a run
block. As to your particular test, armed with this knowledge, it will be possible to construct a unit test using dependency injection mocking and Jasmine's toHaveBeenCalled()
assertion.