Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 558
Kenneth Lynne Avatar asked Mar 13 '13 16:03

Kenneth Lynne


People also ask

How do I test my Angular application?

If Angular CLI is used to manage the Angular projects, it will automatically support Jasmine and Karma Configurations. All you need in order to test your application is to type the command ng test.

Is AngularJS code unit testable?

AngularJS is written with testability in mind, but it still requires that you do the right thing. We tried to make the right thing easy, but if you ignore these guidelines you may end up with an untestable application.

What is the best testing framework for Angular?

When it comes to the Angular world, Jasmine is the recommended testing framework. Angular CLI comes by default with Jasmine and Karma as the test runner. It generates test files at component creation, collects unit tests, runs karma, and displays results on a web page.


2 Answers

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

like image 121
Josh David Miller Avatar answered Oct 15 '22 00:10

Josh David Miller


Just in case you'd like to have a minification-proof version of your provider, things become slightly more complicated.

Here is the provider code:

angular
    .module('core.services')
    .provider('storageService', [function () {
        function isLocalStorageEnabled(window) {
            return true;
        }

        this.$get = ['$window', 'chromeStorageService', 'html5StorageService',
            function($window, chromeStorageService, html5StorageService) {
            return isLocalStorageEnabled($window) ? html5StorageService : chromeStorageService;
        }];
    }]);

The test case:

describe('Storage.Provider', function() {
    var chrome = {engine: 'chrome'};
    var html5 = {engine: 'html5'};
    var storageService, provider;

    beforeEach(module('core.services'));
    beforeEach(function () {
        module(function (storageServiceProvider) {
            provider = storageServiceProvider;
        });
    });
    beforeEach(angular.mock.module(function($provide) {
        $provide.value('html5StorageService', html5);
        $provide.value('chromeStorageService', chrome);
    }));

    // the trick is here
    beforeEach(inject(function($injector) {
        storageService = $injector.invoke(provider.$get);
    }));

    it('should return Html5 storage service being run in a usual browser', function () {
        expect(storageService).toBe(html5);
    });
});

In this case $get is an array and you can't just call it as a usual function providing dependencies as arguments. The solution is to use $injector.invoke().

That's strange that most tutorials and samples miss this detail.

like image 20
sergio Avatar answered Oct 15 '22 00:10

sergio