How can i test a AngularJS provider?

I need to test my own angular provider, and I need to test it in both config and run phase to check that config methods work and that the instantiated provider is indeed configured with the correct parameters.

When I ask dependancy injection for the provider, it can't find the APIResourceFactoryProvider, only the APIResourceFactory, and I haven't found any examples of this on the repositories I've looked trough so far.

It's actually a lot simpler than it would at first seem to test a provider in AngularJS:

describe('Testing a provider', function() {
  var provider;

  beforeEach(module('plunker', function( myServiceProvider ) {
      provider = myServiceProvider;
  }));

  it('should return true on method call', inject(function () {
    expect( provider.method() ).toBeTruthy();
  }));
});

```

The proof is in the Plunker: http://plnkr.co/edit/UkltiSG8sW7ICb9YBZSH

here is a little helper that properly encapsulates fetching providers, hence securing isolation between individual tests:

  /**
   * @description request a provider by name.
   *   IMPORTANT NOTE: 
   *   1) this function must be called before any calls to 'inject',
   *   because it itself calls 'module'.
   *   2) the returned function must be called after any calls to 'module',
   *   because it itself calls 'inject'.
   * @param {string} moduleName
   * @param {string} providerName
   * @returns {function} that returns the requested provider by calling 'inject'
   * usage examples:
    it('fetches a Provider in a "module" step and an "inject" step', 
        function() {
      // 'module' step, no calls to 'inject' before this
      var getProvider = 
        providerGetter('module.containing.provider', 'RequestedProvider');
      // 'inject' step, no calls to 'module' after this
      var requestedProvider = getProvider();
      // done!
      expect(requestedProvider.$get).toBeDefined();
    });
   * 
    it('also fetches a Provider in a single step', function() {
      var requestedProvider = 
        providerGetter('module.containing.provider', 'RequestedProvider')();

      expect(requestedProvider.$get).toBeDefined();
    });
   */
  function providerGetter(moduleName, providerName) {
    var provider;
    module(moduleName, 
           [providerName, function(Provider) { provider = Provider; }]);
    return function() { inject(); return provider; }; // inject calls the above
  }
  • the process of fetching the provider is fully encapsulated: no need for closure variables that compromise isolation between tests.
  • the process can be split in two steps, a 'module' step and an 'inject' step, which can be appropriately grouped with other calls to 'module' and 'inject' within a unit test.
  • if splitting is not required, retrieving a provider can simply be done in a single command!