1

I'm currently trying to test a PubSub service for my angularjs app which will be a buffer between several services.

For example: My Factory A calls $injector to inject my Pubsub service for subscribe/publish without having circular dependencies declarations. And the PubSub calls Service B.

This example works fine. But I'm struggling with the unit tests. Because of this : "Error: Injector already created, can not register a module!" I don't know how to succeed my tests. Any help would be Great, thx.

Added code :

.factory('LocationManager', ['$rootScope', '$state', '$localStorage', '$injector', 'Location', 'Notification',
    function($rootScope, $state, $localStorage, $injector, Location, Notification) {
        var location_mgr = {
            Location: Location,
            saveLocation: saveLocation
        };
        return location_mgr;

        function saveLocation(location) {
            var PubSubManager = $injector.get(['PubSubManager']);
                PubSubManager.subscribe('loadUser', $localStorage.user_id);
                PubSubManager.subscribe('loadProfile', [location.id, 'location']);
            var params = location.id ? {id: location.id} : {};
            var action = location.id ? Location.update : Location.save;
            return action(params, location,
                function (response) {
                    PubSubManager.publish('loadUser', $localStorage.user_id);
                    PubSubManager.publish('loadProfile', [location.id, 'location']);
                    $state.go('ls.location.id.view', {id: response.id});
                },
                function (result) {
                    console.log(result);
                });
        }

.factory('PubSubManager', ['$injector',
    function ($injector) {
        var returnedResult,
            pubsub_mgr = {
                publish: publish,
                subscribe: subscribe,
                unsubscribe: unsubscribe
            };
        return pubsub_mgr;

        function publish(id, params) {
            PubSub.publishSync( id, params );
            return returnedResult;
        }

        function subscribe(id) {
            PubSub.subscribe( id, switchFunction );
        }

        function unsubscribe(id) {
            PubSub( id ).unsubscribe( id );
        }

        function switchFunction(id, params) {
            switch (id) {
                case 'getLocations':
                    $injector.invoke(function (LocationManager) {
                        returnedResult = LocationManager.getLocations(params);
                    });
                    break;
                default:
                    break;
            }
        }
    }]);

The unit test :

describe("LocationManager factory:", function () {
var httpBackend, rootScope, state, localStorage;
var LocationManager, Location;

beforeEach(module('ionic', 'ngResource', 'ui-notification', 'ngStorage'));
beforeEach(module('location_services'));

beforeEach(inject(function ($httpBackend, _$rootScope_, _$state_, _$localStorage_, _LocationManager_, _Location_) {
    httpBackend = $httpBackend;
    rootScope = _$rootScope_;
    state = _$state_;
    localStorage = _$localStorage_
    LocationManager = _LocationManager_;
    Location = _Location_;
}));

describe('saveLocation function,', function () {
    it('should create a location', function () {
        beforeEach(module('pubSub_services'));
        beforeEach(function () {
            spyOn(state, 'go');
        });
        httpBackend.expect('POST', '/api/location').respond({status: 200, message: ''});
        var location = {
            name: 'new_location'
        };
        LocationManager.saveLocation(location).$promise.then(
            function (result) {
                data = result;
                expect(state.go).toHaveBeenCalled();
            }
        );
        httpBackend.flush();
        expect(data.status).toBe(200);
    });
Okyne
  • 95
  • 9
  • 1
    If PubSub is aware of Service B, this sounds more like a Mediator than a Pub/Sub. – Ates Goral Nov 27 '15 at 15:08
  • 1
    Can't you inverse the dependency and let Factory B inject PubSub and just subscribe to events on it? – Ates Goral Nov 27 '15 at 15:09
  • You're totally RIGHT. I'm gonna change my code to rewrite a "real" pubSub pattern and not a Mediator pattern. Hope this will fix my unit tests. – Okyne Nov 27 '15 at 15:28
  • Possible duplicate of [Using $injector in AngularJS when integration testing (without using ngMock)](http://stackoverflow.com/questions/30226062/using-injector-in-angularjs-when-integration-testing-without-using-ngmock) – Paul Sweatte Jan 30 '17 at 22:22

0 Answers0