title: How to write testable controllers with private methods in AngularJs?
body: <p>Alright, so I have been stumbling upon some issue for a long time and I would like to hear an opinion from the rest of community.</p>
  
  <p>First, let's look at some abstract controller.</p>
  
  <pre><code>function Ctrl($scope, anyService) {
  
     $scope.field = "field";
     $scope.whenClicked = function() {
        util();
     };
  
     function util() {
        anyService.doSmth();
     }
  
  }
  </code></pre>
  
  <p>Clearly we have here:</p>
  
  <ul>
  <li>regular scaffold for controller with <code>$scope</code> and some service injected</li>
  <li>some field and function attached to the scope</li>
  <li>private method <code>util()</code></li>
  </ul>
  
  <p>Now, I'd like to cover this class in unit tests (Jasmine). However, the problem is that I want to verify that when I click (call <code>whenClicked()</code>) some item that the <code>util()</code> method will be called. I don't know how to do that, since in Jasmine tests I'm always getting errors that either the mock for <code>util()</code> hasn't been defined or was not called.</p>
  
  <p><strong>Note: I'm not trying to fix this particular example, I'm asking about testing such code pattern in general. So please don't tell me "what is exact error". I'm asking how to do that, not how to fix this.</strong></p>
  
  <p>I have been trying a number of ways around this:</p>
  
  <ul>
  <li>obviously I cannot use <code>$scope</code> in my unit tests as I don't have this function attached to this object (it usually ends with message <code>Expected spy but got undefined</code> or similar)</li>
  <li>I tried attaching those functions to the controller object via <code>Ctrl.util = util;</code> and then verifying mocks like <code>Ctrl.util = jasmine.createSpy()</code> but in this case <code>Ctrl.util</code> is not being called so tests fail</li>
  <li>I tried to change <code>util()</code> to be attached to <code>this</code> object and mocking <code>Ctrl.util</code> again, with no luck</li>
  </ul>
  
  <p>Well, I cannot find my way around this, I would expect some help from JS ninjas, a working fiddle would be perfect.</p>