4

I'm using Jasmine to unit test my Angular App. How can I test form validation in my controller? For example, I have a login function:

$scope.login = function() {
    if($scope.form_login.$valid) {
      //send request with username and password
    };
};

I'm trying to set $valid to true, but I can't access the form here. I got an error TypeError: Cannot set property '$valid' of undefined:

it('should not send request if form validation fails', function() {
    $controller('loginController', {$scope: $scope});
    $scope.form_login.$valid = true;
    $scope.login();
})

2 Answers 2

3

Unit test should not really test the form. To test the form and other not controller related things use e2e testing.

However if you really want to test validation in unit test see To test a custom validation angularjs directive or How to unit test angularjs form?

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

2 Comments

Correct answer, move as much code logic as possible from view into controller and test controller code with unit tests, use protractor e2e testing for form testing
@danday74 If use a service to login, I could be testing that service not have been called the method in a unit testing approach, and also, i could be testing in a integration approach using e2e protractor
1

If you uses a service for save the data

$scope.login = function() {
    if($scope.form_login.$valid) {
      //send request with username and password
      MyService.login();
    };
};

Check if your service have not been called and mock the $scope.form_login.$valid property to false;

var MyService, controllerInjector, rootScope;
beforeEach(inject(function($controller, _MyService_, $rootScope){

  controllerInjector = $controller;
  MyService = _MyService_;
  rootScope = $rootScope;

}))

it('should not send request if form validation fails', function() {
  var scope, controller;
  scope = rootScope.$new();
  scope.form_login = {
    $valid : false;
  }
  var loginController = controllerInjector('loginController', {
    $scope : scope
  });

  spyOn(MyService,'login');

  scope.login();

  expect(MyService.login).not.toHaveBeenCalled();

});

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.