Search code examples
angularjsunit-testingangular-providers

How to mock config-phase providers for unit tests?


I'm writing a spec that checks a method is called during the config phase of the Angular module under test.

Here's a simplified look at the code being tested:

angular.module('core',['services.configAction'])
    .config(function(configAction){
        configAction.deferIntercept(true);
    });

What happens above is we define a core module that has a single dependency.
Then, in the config-block of the core module, we call the deferIntercept method on the configAction object given to use from services.configAction.

I'm trying to test that core's config calls that method.

This is the current setup:

describe('core',function()
{
    const configActionProvider={
        deferIntercept:jasmine.createSpy('deferIntercept'),
        $get:function(){
            return {/*...*/}
        }
    };

    beforeEach(function()
    {
        module(function($provide)
        {
            $provide.provider('configAction',configActionProvider);
        });

        module('core.AppInitializer');

        inject(function($injector)
        {
            //...
        });
    });

    it('should call deferIntercept',function()
    {
        expect(configActionProvider.deferIntercept).toHaveBeenCalledWith(true);
    });
});

The problem with that is that it doesn't override configAction and so the spy is never called, the original method is.
It will do so if I remove it as a dependency of the core module, so angular.module('core',[]) instead of angular.module('core',['services.configAction']) will work and the spy is called.

Any idea how to override services.configAction during testing without removing it from the dependency list?


Solution

  • Have a look at - https://dzone.com/articles/unit-testing-config-and-run. Something like the following -

    module('services.configAction', function (configAction) {
      mockConfigAction = configAction;
      spyOn(mockConfigAction, 'deferIntercept').andCallThrough();
    });
    module('core');
    

    in your beforeEach might do the job.