title: Unit testing in AngularJS - Mocking Services and Promises
body: <p>In Angular everything seems to have a steep learning curve and unit testing an Angular app definitely doesn't escape this paradigm. </p>
  
  <p>When I started with TDD and Angular I felt that I was spending twice (maybe more) as much time figuring out just how to test and maybe even more just getting my tests set up correctly. But as <a href="http://www.bennadel.com/blog/2439-My-Experience-With-AngularJS-The-Super-heroic-JavaScript-MVW-Framework.htm" rel="noreferrer">Ben Nadel</a> put it in his blog there are ups and downs in the angular learning process. His graph is definitely my experience with Angular.</p>
  
  <p>However as I have progressed in learning Angular and unit testing as well, now i feel that I am spending much less time setting up tests and much more time making tests go from red to green - which is a good feeling. </p>
  
  <p>So I have come across different methods of setting up my unit test to mock services and promises and I thought I would share what I have learned and also ask the question of:</p>
  
  <blockquote>
    <p>Are there any other or better ways of accomplishing this?</p>
  </blockquote>
  
  <p>So onto the code, that what we all come for here anyways - not to listen to some guy talk about his love, err accomplishments learning a framework. </p>
  
  <p>This is how I started out mocking my services and promises, I'll use a controller, but services and promises can be mocked in other places obviously. </p>
  
  <pre><code>describe('Controller: Products', function () {
      var//iable declarations
          $scope,
          $rootScope,
          ProductsMock = {
              getProducts: function () {
              } // There might be other methods as well but I'll stick to one for the sake of consiseness
          },
          PRODUCTS = [{},{},{}]
      ;
  
      beforeEach(function () {
          module('App.Controllers.Products');
      });
  
      beforeEach(inject(function ($controller, _$rootScope_) {
          //Set up our mocked promise
          var promise = { then: jasmine.createSpy() };
  
          //Set up our scope
          $rootScope = _$rootScope_;
          $scope = $rootScope.$new();
  
          //Set up our spies
          spyOn(ProductsMock, 'getProducts').andReturn(promise);
  
          //Initialize the controller
          $controller('ProductsController', {
              $scope: $scope,
              Products: ProductsMock
          });
  
          //Resolve the promise
          promise.then.mostRecentCall.args[0](PRODUCTS);
  
      }));
  
      describe('Some Functionality', function () {
          it('should do some stuff', function () {
              expect('Stuff to happen');
          });
      });
  });
  </code></pre>
  
  <p>For us this worked, but as time went on I thought there must be a better way. For one I hated the</p>
  
  <pre><code>promise.then.mostRecentCall 
  </code></pre>
  
  <p><em>thing</em>, and if we wanted to reinitialise the controller then we had to pull it out of the beforeEach block and inject it individually into each test. </p>
  
  <blockquote>
    <p>There has to be a better way...</p>
  </blockquote>
  
  <p>Now I ask does anyone have other ways to set tests up, or and thoughts or feeling on the way I have chose to do it?</p>