Dianhuro
Dianhuro

Reputation: 5

How to test an angular $scope function?

I'm trying make a test for my angular control. How do I test a variable that is in a function?

example:

$scope.onFileSelect = function($files) {
$scope.selectedFiles = [];
$scope.progress = [];

if ($scope.upload && $scope.upload.length > 0) {
  for (var i = 0; i < $scope.upload.length; i++) {
    if ($scope.upload[i] !== null) {
      $scope.upload[i].abort();
    }
  }
}
$scope.upload = [];
$scope.uploadResult = [];
$scope.selectedFiles = $files;
$scope.dataUrls = [];



    if ($scope.selectedFiles.length==1) {
      for ( var i = 0; i < $files.length; i++) {
        var $file = $files[i];
        if (window.FileReader && $file.type.indexOf('image') > -1) {
          var fileReader = new FileReader();
          fileReader.readAsDataURL($files[i]);
          var loadFile = function(fileReader, index) {
            fileReader.onload = function(e) {
              $timeout(function() {
                $scope.dataUrls[index] = e.target.result;
              });
            };
          }(fileReader, i);
        }
        $scope.progress[i] = -1;
        if ($scope.uploadRightAway) {
          $scope.start(i);
        }
      }

    }
    else{
      $scope.selectedFiles = null;
      $scope.clientmsg={};
      $scope.errormessageheader="";
      $scope.uploadErrors="";
      $scope.UploadSuccess="";
      auxArray = [""];
      $scope.uploadErrors =auxArray;
      $scope.errormessageheader="Only_submit_one_file";
    }
  };

and my test...

describe('Unit: routeAssignUpload_Ctrl', function () {

beforeEach(angular.mock.module('primaryDistributionApp'));

var ctrl, scope;
// inject the $controller and $rootScope services
// in the beforeEach block
beforeEach(inject(function($controller, $rootScope) {
// Create a new scope that's a child of the $rootScope
scope = $rootScope.$new();
// Create the controller
ctrl = $controller('routeAssignUpload_Ctrl', {
  $scope: scope
});
}));



it('probando funcion onFileSelect',function(){
expect(scope.onFileSelect).toBeDefined();
var onFileSelect1 = new scope.onFileSelect;
spyOn(onFileSelect1).andCallThrough();
expect(scope.upload).toBeDefined();
});


})

the result is "TypeError: 'undefined' is not an object" (evaluating '$scope.selectedFile s.length') I don't understand why, can anyone help me?

Upvotes: 0

Views: 569

Answers (1)

bloveridge
bloveridge

Reputation: 271

A few things to consider.

  1. Why are you using the new keyword when trying to call scope.onFileSelect? This is just a scope method, you don't need to (and probably don't want to) use it as a constructor method.
  2. You aren't passing any variable into scope.onFileSelect. This means the $files variable is undefined. You then assign it via $scope.selectedFiles = $files; and test its length (if ($scope.selectedFiles.length==1) { ... }). As the error indicates, undefined has no length property.

I also don't see any reason you need to spy on onFileSelect -- you are testing its behavior, and you are calling it directly; using spyOn(..).andCallThrough is most useful when you want to test that some other function calls into this for your, without interrupting its behavior. Your test could probably be better written as follows (flesh out to test more interesting behavior):

it('probando funcion onFileSelect',function(){
    var files = ['fileA', 'fileB'];
    expect(scope.onFileSelect).toBeDefined();
    scope.onFileSelect(files);
    expect(scope.selectedFiles).toBe(files);
    expect(scope.upload).toBeDefined(); // or whatever
});

The question you should be asking yourself is what behavior you are really trying to test. Currently, this isn't a very interesting test -- you know that upload is defined, but you don't know anything interesting about it yet.

Upvotes: 1

Related Questions