title: Jasmine cannot read property of undefined
body: <p>I usually don't post the whole stack trace, but I've been having this problem with one individual unit test and it's driving me nuts.  I've rewritten it at least 10 different times and 20 different ways, and I keep getting the same error.</p>
  
  <pre><code>TypeError: Cannot read property 'allAccountRangeFlag' of undefined
      at Scope.$scope.disableAddAllButton (http://localhost:9876/base/main/webapp/scripts/components/directives/shuffleBox/shuffleBox.js:9:4528)
      at Object.$parseFunctionCall [as get] (http://localhost:9876/base/main/webapp/bower_components/angular/angular.js:12404:18)
      at Scope.$digest (http://localhost:9876/base/main/webapp/bower_components/angular/angular.js:14300:40)
      at Object.&lt;anonymous&gt; (http://localhost:9876/base/test/javascript/spec/components/directives/shuffleBox/shuffleBox.spec.js:53:20)
      at attemptSync (http://localhost:9876/absoluteC:/data/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1757:24)
      at QueueRunner.run (http://localhost:9876/absoluteC:/data/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1745:9)
      at QueueRunner.execute (http://localhost:9876/absoluteC:/data/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1731:10)
      at Spec.Env.queueRunnerFactory (http://localhost:9876/absoluteC:/data/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:569:35)
      at Spec.execute (http://localhost:9876/absoluteC:/data/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:318:10)
      at Object.fn (http://localhost:9876/absoluteC:/data/rulemanager/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:2071:43)
  </code></pre>
  
  <p>I am unit testing an Angular directive.  The directive has a controller, which has functions, which use global variables.  <code>allAccountRangeFlag</code> is one of those variables.</p>
  
  <p>This is a snippet of the directive that is being tested:</p>
  
  <pre><code>app.directive('shuffleBox', function() {
      var controller = ['$scope', '$filter', function($scope, $filter) {
          $scope.disableAddButton = function() {
               if(!$scope.args.allAccountRangeFlag) {
                    // do stuff with filtered data and $filter
               }
           };
      }];
  
      return {
           ...,
           controller: controller,        
           ...
      };
  });
  </code></pre>
  
  <p>And the test itself, in its simplest form:</p>
  
  <pre><code>describe('shuffleBox directive', function() {
      var $compile,
          $rootScope,
          shuffleBoxargs = { 
               availableValues : [],
               key : 'id',
               selectedValues : [],
               searchText : '',
               allAccountRangeFlag : false
           };
  
      beforeEach(module('app'));
      beforeEach(module('path/to/shuffleBox.html'));
  
      beforeEach(inject(function(_$compile_, _$rootScope_) {
          $compile = _$compile_;
          $rootScope = _$rootScope_;
      }));
  
      it('should compile', function() {
          var element = $compile('&lt;div shuffle-box args="shuffleBoxargs"&gt;&lt;/div&gt;')($rootScope);
          $rootScope.$digest();
          expect(element.html()).not.toBeNull();
      });
  });
  </code></pre>
  
  <p><strong>UPDATE</strong>: I wasn't injecting enough "stuff" in the <code>beforeEach</code> block:</p>
  
  <pre><code>describe('shuffleBox', function() {      
  
      beforeEach(module('app'));
      beforeEach(module('scripts/components/directives/shuffleBox/shuffleBox.html'));
  
      //properties to hold shuffleBox selections
      var shuffleBoxargs = { 
          availableValues : [],
          key : 'id',
          selectedValues : [],
          searchText : '',
          allAccountRangeFlag : false
      };  
  
      beforeEach(inject(function($templateCache, _$compile_, _$rootScope_, _$filter_) {
          template = $templateCache.get('main/webapp/scripts/components/directives/shuffleBox/shuffleBox.html');
          $templateCache.put('main/webapp/scripts/components/directives/shuffleBox/shuffleBox.html', template);
          $compile = _$compile_;
          $rootScope = _$rootScope_;
          $filter = _$filter_;
  
          var sbElement = angular.element('&lt;div shuffle-box args="shuffleBoxargs" &gt;&lt;/div&gt;');
          var element = $compile(sbElement)($rootScope);
          scope = element.isolateScope() || element.scope();  
          scope.args = shuffleBoxargs;
  
          // Grab controller instance
          controller = element.controller("shuffleController");
          $rootScope.$digest();
      }));
  
  
  
      it('shuffle-box directive', function() {
          expect(scope.disableAddAllButton()).toBeDefined();    
      });    
  });
  </code></pre>
  
  <p>However, now I am getting a new error:</p>
  
  <pre><code>PhantomJS 2.0.0 (Windows 7 0.0.0) shuffleBox shuffle-box directive FAILED
          undefined
                  at disableAddAllButton (C:/data/shuffleBox.js:9:4528)
                  at $parseFunctionCall (C:/data/bower_components/angular/angular.js:12404:23)
                  at $digest (C:/data/bower_components/angular/angular.js:14300:43)
                  at C:/data/shuffleBox.spec.js:35:27
                  at invoke (C:/data/bower_components/angular/angular.js:4203:22)
                  at workFn (C:/data/bower_components/angular-mocks/angular-mocks.js:2436:26)
          TypeError: undefined is not a constructor (evaluating 'scope.disableAddAllButton()') in C:/data/shuffleBox.spec.js (line 41)
                  at C:/data/shuffleBox.spec.js:41:41
  PhantomJS 2.0.0 (Windows 7 0.0.0): Executed 474 of 507 (1 FAILED) (0 secs / 3.078 secs)
  PhantomJS 2.0.0 (Windows 7 0.0.0) shuffleBox shuffle-box directive FAILED
          undefined
                  at disableAddAllButton (C:/data//shuffleBox.js:9:4528)
                  at $parseFunctionCall (C:/data/bower_components/angular/angular.js:12404:23)
                  at $digest (C:/data/bower_components/angular/angular.js:14300:43)
                  at C:/data/shuffleBox.spec.js:35:27
                  at invoke (C:/data/bower_components/angular/angular.js:4203:22)
                  at workFn (C:/data/bower_components/angular-mocks/angular-mocks.js:2436:26)
          TypeError: undefined is not a constructor (evaluating 'scope.disableAddAllButton()') in C:/data/shuffleBox.spec.js (line 41)
  PhantomJS 2.0.0 (Windows 7 0.0.0): Executed 495 of 507 (1 FAILED) (3.391 secs / 3.204 secs)
  </code></pre>
  
  <p><code>scope.disableAddAllButton()</code> is a function in the <code>shuffleController</code>.</p>