1

I'm trying to test a simple form controller using the controller as syntax. What I want is to be able to pass in different field values to each unit test and see how the controller reacts. The code I'm using as an example:

Controller:

angular.module('auth').controller('LoginFormCtrl',['AuthService',function(AuthService) {
  var self = this;

  self.non_field_errors = {};

  self.login = function(){
    AuthService.login(self.login_details.username,self.login_details.password)
        .then(function(){
            //do routing stuff here
        },function(response){
            if('non_field_errors' in response){
                self.non_field_errors = response.non_field_errors;
            }
        });
    };
}]);

Test:

describe('LoginFormCtrl', function() {

var scope; //scope to bind controller to
var ctrl; //Controller to be tested

beforeEach(module('auth'));

//Mock out AuthService
beforeEach(module(function($provide){

    authService = {
        login: function(username,password){
            var deferred = $q.defer();
            if(username == 'test1' && password == 'password1'){
                deferred.resolve();
            }else{
                deferred.reject({non_field_errors:['non_field_error_1']});
            }
            return deferred;
        }
    };
    $provide.value('AuthService',authService);

}));

//Set up scope
beforeEach(inject(function($rootScope){
    scope = $rootScope.$new();
}));

//Set up spies
beforeEach(inject(function(AuthService){
    spyOn(AuthService,'login').andCallThrough();
}));

//Clean Up
afterEach(function(){
    ctrl = null;
});

it('should log the user in if they provide the correct details', inject(function($controller){

    ctrl = $controller('LoginFormCtrl',scope,{
        login_details:{
            username:'test1',
            password:'password1',
        }
    });

    ctrl.login();
    expect(AuthService.login).toHaveBeenCalledWith('test1','password1');
})); 

});

I've tried a few different approaches such as creating a scope and directly manipulating the ctrl variable. What is the best way to do this kind of testing?

1 Answer 1

1

Start by instantiating the controller:

ctrl = $controller('LoginFormCtrl');

Angular will inject the AuthService. There is no other dependency to inject in the controller, so passing a scope or login_details won't work.

Then set its login_details:

ctrl.login_details = {
    username: 'test1',
    password: 'password1'
};

Then call the function to test:

ctrl.login();
Sign up to request clarification or add additional context in comments.

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.