Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

running jasmine angular tests without karma

I have a working angular application that I need to write unit tests for (I know normally it's the other way around).

Whenever I run my jasmine task I get following error:

ReferenceError: Can't find variable: ApplicationService

We just want to run the tests in phantomJS without karma is this possible and if so, can you look at my code and tell me what's going haywire.

I've added a jasmine task to my gruntfile that looks like this:

jasmine:{
        src: ['src/main/js/**/*.js'],
        options:{
            specs: 'src/test/js/**/*.js',
            vendor: [ 'src/test/lib/**/*.js', 'src/main/lib/js/*.js']
        }
},

The service I'm trying to test is located in the file 'src/main/js/services/ApplicationService.js' and looks like this:

(function(){

'use strict';

var services = angular.module('portal.services');

services.factory('ApplicationService', ['ApplicationData', 'localStorageService' ,'UserService', function(ApplicationData, localStorageService, UserService){
    return new ApplicationService(ApplicationData, localStorageService, UserService);
}]);

function ApplicationService(ApplicationData, localStorageService, UserService){
    this.applicationData = ApplicationData;
    this.localStorageService = localStorageService;
    this.userService = UserService;
}

ApplicationService.prototype.getApplications = function(entity){
    var locale = this.userService.getUserinfoLocale();
    var applications = this.localStorageService.get(Constants.key_applications+locale+'_'+entity);
    if(applications !== null && applications !== undefined){
        return JSON.parse(applications);
    } else {
        return this.applicationData.getApplications().query({locale: locale, entity: entity}, $.proxy(function(data){
            this.save(Constants.key_applications+locale+'_'+entity, JSON.stringify(data));
        }, this));
    }
};

}());

And my test file is located in 'src/test/js/services/ApplicationServiceTest.js' and looks like this:

(function () {

'use strict';

describe('ApplicationService.js unit test suite', function () {

    var applicationData, localStorageService, userService = null;
    var applicationService = new ApplicationService(applicationData, localStorageService, userService);

    beforeEach(function () {
        applicationData = {
            getApplications:function () {
                return {application1:'yess', application2:'okay'};
            }
        };
        localStorageService = {
            get:function (key) {
                if (key === Constants.key_applications + 'nl_ESS')
                    return JSON.stringify({application1:'name1'});
                else if (key === Constants.key_applications + 'nl_SVF')
                    return JSON.stringify({application1:'name2'});
                else if (key === Constants.key_applications + 'nl_MED')
                    return JSON.stringify({application1:'name3'});
            },
            add:function (key, value) {

            }
        };
        userService = {
            getUserinfoLocale:function () {
                return 'nl';
            }
        };
    });


    it('ApplicationService.getApplications should delegate to ApplicationData.getApplications', function () {
        var applicationService =
        spyOn(localStorageService, get(Constants.key_applications + 'nl_ESS')).andReturn(null);
        spyOn(applicationData, 'getApplications');
        expect(applicationService.getApplications()).toBe({application1:'name1', application2:'name2'});
        expect(applicationData.getApplications).toHaveBeenCalled();
    });

    it('ApplicationService.getApplications should use the localsStorageService cache', function () {

    });

});
}());
like image 274
J.Pip Avatar asked Oct 21 '22 18:10

J.Pip


1 Answers

I know this is a really old question, but just in case it's still valid or others are having the same question: You don't expose any of the ApplicationService in ApplicationService.js to the outside world because you put a (function () {...})() around it so there is no way to instantiate it in your tests.

If you want to test this the agular way you should use angular-mocks and especially the module() and inject() functions it provides. This will allow you to inject the service into your tests.

If you want to test this the "POJO" way you should expose the ApplicationService in some way. Removing the function wrapper would be the simplest way, but that would break the nice isolation that you made to only expose it as a service. Therefore my advice would be to use angular-mocks.

like image 178
Simon Groenewolt Avatar answered Oct 24 '22 18:10

Simon Groenewolt