1

Lets see, we have this according to:https://docs.angularjs.org/guide/unit-testing

describe('PasswordController', function() {
  beforeEach(module('app'));

  var $controller;

  beforeEach(inject(function(_$controller_){
    // The injector unwraps the underscores (_) from around the parameter names when matching
    $controller = _$controller_;
  }));

  describe('$scope.grade', function() {
    it('sets the strength to "strong" if the password length is >8 chars', function() {
      var $scope = {};
      var controller = $controller('PasswordController', { $scope: $scope });
      $scope.password = 'longerthaneightchars';
      $scope.grade();
      expect($scope.strength).toEqual('strong');
    });
  });
});

now i am making service and factory, is there any equivalent to ____$controller____ for service and factory? so i can inject it with something else like:

var controller = $controller('PasswordController', { $scope: $scope });

and change the inner functions of the dependency so i can test it, or is there any better approach?

Edit: to make question more clear here is the example of the question:

i have this:

var app = angular.module("app").service("MyService",["$scope","$http",function($scope,$http){
    this.myFunction = function(){
        $http.get("/myApi/1");
    }
}]);

how do i use the equivalent of

var controller = $controller('PasswordController', { $scope: $scope });

so i can inject $scope and $http with something else to myService?

7
  • Did my answer help? Commented Oct 25, 2016 at 9:59
  • no, i am asking about the equivalent of $controller for service and factory so i can inject the dependency, not asking how to inject the dependency in controller, Commented Oct 25, 2016 at 10:37
  • so i can inject the dependency - inject where? Commented Oct 25, 2016 at 10:38
  • controller = $controller('PasswordController', { $scope: my_own_pseudo_dependency }); Commented Oct 25, 2016 at 10:40
  • I showed you that in my answer, search for controllerDependency: controllerDependency . Commented Oct 25, 2016 at 10:41

2 Answers 2

2

You can't inject dependencies to factories or services on the go, but you can mock the dependencies with your custom objects and have angular substitute them automatically. You can use $provide for that. Here is an example:

angular.module('app').service('some', function(dependencyService) {

});

When testing:

beforeEach(module(function($provide) {
   $provide.value('dependencyService', {

   });
}));
Sign up to request clarification or add additional context in comments.

10 Comments

unfortunately, the $provide.value is not a function, i noticed that yours quite similar to sitepoint.com/…, but if i follow sitepoint, i got the error where you can't initialize module after injector initialized
@HansYulian, so how is your progress?
Sorry for late reply, i already go back from office yesterday. here is the code: (function () { describe("Testing service", function () { beforeEach(function ($provide) { $provide.value("$http", function () { this.get = function (target, header) { return "ok"; } }); }); var APIServiceObject; beforeEach(inject(function (APIService) { APIServiceObject = APIService; })); it("test", function () { expect(APIServiceObject.getHeader()).toEqual({}); }); }); })();
@HansYulian, updated, module call was missing. Please see if it's working now.
Oh i finally got the answer but from somewhere else, i will put it here
|
1

After doing a workarround, i found out from https://www.sitepoint.com/unit-testing-angularjs-services-controllers-providers/ about the service. i tested out the tutorial here and here is the test script:

(function () {
    angular.module('services', [])
        .service('sampleSvc', ['$window', 'modalSvc', function ($window, modalSvc) {
            this.showDialog = function (message, title) {
                if (title) {
                    modalSvc.showModalDialog({
                        title: title,
                        message: message
                    });
                } else {
                    $window.alert(message);
                }
            };
      }]);
    describe("Testing service", function () {
        var mockWindow, mockModalSvc, sampleSvcObj;
        beforeEach(module(function ($provide) {
                $provide.service('$window', function () {
                    this.alert = jasmine.createSpy('alert');
                });
                $provide.service('modalSvc', function () {
                    this.showModalDialog = jasmine.createSpy('showModalDialog');
                });
            }, 'services'));

        beforeEach(inject(function ($window, modalSvc, sampleSvc) {
            mockWindow = $window;
            mockModalSvc = modalSvc;
            sampleSvcObj = sampleSvc;
        }));
        it('should show alert when title is not passed into showDialog', function () {
            var message = "Some message";
            sampleSvcObj.showDialog(message);

            expect(mockWindow.alert).toHaveBeenCalledWith(message);
            expect(mockModalSvc.showModalDialog).not.toHaveBeenCalled();
        });

        it('should show modal when title is passed into showDialog', function () {
            var message = "Some message";
            var title = "Some title";
            sampleSvcObj.showDialog(message, title);

            expect(mockModalSvc.showModalDialog).toHaveBeenCalledWith({
                message: message,
                title: title
            });
            expect(mockWindow.alert).not.toHaveBeenCalled();
        });
    });
})();

and i try my own test script:

(function () {
    describe("Testing service", function () {
        var mockHttp, mockCookies, mockApi;
        beforeEach(function () {
            module(function ($provide) {
                $provide.service('$http', function () {
                    this.defaults = {
                        headers: {
                            common: {

                            }
                        }
                    };
                });
                $provide.service('$cookies', function () {

                });
            });
            module('timesheet');
        });

        beforeEach(inject(function ($http, $cookies, APIService) {
            mockHttp = $http;
            mockCookies = $cookies;
            mockApi = APIService;
        }));
        it('Test Service', function () {

        });
    });
})();

apparently in somewhere in my code, there is an app.run which inside do the

$http.defaults.headers.common.Authorization = 'Bearer ' + $cookies.get('sessionToken');

and causes the error the moment i inject the $http with something else because headers not defined, i thought it was from my own test script because they are using same name, but apparently this is the one causing problem.

So, actually the moment we load in testing mode, the angularjs still do the whole running of application, in which i forgot about this one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.