1

I have a simple login controller:

'use strict';

angular.module('login', ['ngRoute'])
    .config(['$routeProvider', function ($routeProvider) {

    }])
    .controller('LoginCtrl', ["$scope", "$route", "LoginService", function ($scope, $route, LoginService) {
        var self = this;
        this.showGuestLogin = true;
        this.showUserLogin = false;

        this.toggleUserLoginType = function () {
            this.showGuestLogin = !this.showGuestLogin; 
            this.showUserLogin = !this.showUserLogin;
        }

        this.submitGuestLogin = function()
        {
            if(this.guestName === undefined || this.guestName.trim() == '')
            {
                self.loginError = "Name cannot be blank";
                return; 
            }

            LoginService.loginAsGuest(this.guestName.trim())
            .then(function()
            {
                self.loginError = null;
                $route.reload();
            })
            .catch(function(err)
            {
                self.loginError = 'An error occured. Please try again';
            });
        }
    }]);

I am trying to test it with:

describe('LoginCtrl', function()
{
    beforeEach(module('login'));

    var ctrl;

    beforeEach(inject(function($controller)
    {
        ctrl = $controller('LoginCtrl');
    }));

    it('should set error if guest name is undefined', function(done)
    {
        ctrl.guestName = undefined;
        ctrl.submitGuestLogin();
        expect(ctrl.loginError).toBeDefined();
    });
});

But I am getting this error in console when test runs

Error: [$injector:unpr] http://errors.angularjs.org/1.5.8/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope%20%3C-%20LoginCtrl

I can see in the developer console in the karma driven browser that the controller and it's dependant files are all being loaded correctly.

I can't see what is wrong?

UPDATE

I have tried the suggestions of passing an empty object:

beforeEach(inject(function($controller, $scope, $route, LoginService)
{
    ctrl = $controller('LoginCtrl', { 

    });
}));

and setting up the dependencies:

beforeEach(inject(function($controller, $scope, $route, LoginService)
{
    ctrl = $controller('LoginCtrl', { 
        $scope: $scope,
        $route: $route,
        LoginService: LoginService
    });
}));

Both of which give me this error:

Error: [$injector:unpr] http://errors.angularjs.org/1.5.8/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope

5
  • Oh, I see I am not the only one with this odd problem...I haven't figured it out but seems to me something is wrong with the generator. Are you using a generator? Commented Nov 22, 2016 at 16:57
  • You mean a boilerplate code generator? If so, no, started from scratch. Got tests around my services that run fine too. Commented Nov 22, 2016 at 17:00
  • Probably you forgot a second parameter in this line ctrl = $controller('LoginCtrl');. You should add an object as the second parameter eg. ctrl = $controller('LoginCtrl', { });. This second mocks Controller's scope. Commented Nov 22, 2016 at 17:03
  • I added an empty object, different error. Commented Nov 22, 2016 at 17:18
  • It's still to broad. Could you please add some more information such as, which libs you are using. For more information, try to access this link - Testing AngularJS Commented Nov 22, 2016 at 17:24

2 Answers 2

2

It's because you need to add in the scope in the injection like this:

beforeEach(inject(function($controller, $scope) {
    ctrl = $controller('LoginCtrl', { $scope: $scope });
}));

Similarly, if your real controller has injections that you will be using for testing, you'll need to add them in. So for example (and this is only an example):

ctrl = $controller('LoginCtrl',
  {
    $scope: $scope,
    SomeService: SomeService,
    moment: moment,
    dateFormat: dateFormat
  });
Sign up to request clarification or add additional context in comments.

2 Comments

I have tried beforeEach(inject(function($controller, $scope, $route, LoginService) { ctrl = $controller('LoginCtrl', { $scope: $scope, $route: $route, LoginService: LoginService }); })); to match the controller but now I get this error: Error: [$injector:unpr] htt p://errors.angularjs.org/1.5.8/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope
@Si-N Still sounds like a familiar problem to me. I also have tried the above solution, but that is not the problem.
0

Found an answer here which worked: Angular Unit Test Unknown provider: $scopeProvider

beforeEach(inject(function($controller, $rootScope, $route, LoginService)
{
    scope = $rootScope.$new();

    ctrl = $controller('LoginCtrl', { 
        $scope: scope
    });
}));

In my case I didn't actually need $scope injected into my controller, so I removed it an the original code now works:

beforeEach(inject(function($controller, $rootScope, $route, LoginService)
{
        ctrl = $controller('LoginCtrl');
}));

I need to read up on how mocks and injection works!

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.