Run blocks in Angular are commonly used to bootstrap the application and run initial setup functions. In some cases the logic might be complex enough to warrant unit tests, so in the following post, I will demonstrate how to capture run block(s) from a unit test.
Run blocks in Angular are commonly used to bootstrap the application and run initial setup functions. In some cases the logic might be complex enough to warrant unit tests, so in the following post, I will demonstrate how to capture run block(s) from a unit test.
Below is an example of two different run blocks wired up to the same Angular application.
angular.module('app').run(['applicationReadyService',function(applicationReadyService){ applicationReadyService.done(1); }]); angular.module('app').run(['applicationReadyService',function(applicationReadyService){ applicationReadyService.done(3); }]);
The trick to testing this is to grab the callback functions of the run blocks and run them as regular methods in the test. It turns out that Angular exposes these callback through a private _runBlocks array.
The callback can then be indexed directly in the array as the last item in the captured run block as shown in the code below.
describe('run module test', function(){ it('should call done methods in module', function(){ var myModule = angular.module('app'); var firstRunBlockCallback = myModule._runBlocks[0][myModule._runBlocks[0].length - 1]; var secondRunBlockCallBack = myModule._runBlocks[1][myModule._runBlocks[1].length - 1]; var applicationReadyServiceMock = {done:function(){}}; spyOn(applicationReadyServiceMock,'done'); firstRunBlockCallback(applicationReadyServiceMock); expect(applicationReadyServiceMock.done).toHaveBeenCalledWith(1); secondRunBlockCallBack(applicationReadyServiceMock); expect(applicationReadyServiceMock.done).toHaveBeenCalledWith(3); }); });
The example might almost be too trivial in this case, but the functionality is intentionally kept simple in order to illustrate how the test can gain access to the seemingly closed off run blocks.
I have added a couple of simple expects to detect that the done method of the applicationReadyService was called with the appropriate parameter.