AngularJS: mocking services.

by Puigcerber

HTML

<script src="http://jasmine.github.io/1.3/lib/jasmine.js"></script>
<script src="http://jasmine.github.io/1.3/lib/jasmine-html.js"></script>
<link rel="stylesheet" href="http://jasmine.github.io/1.3/lib/jasmine.css">
<script src="https://code.angularjs.org/1.2.1/angular-mocks.js"></script>
<div ng-app="webApp" style="display: none">
    <div ng-controller="ContactCtrl as contact">
        <form name="contactForm" ng-submit="contact.submitForm()">
            <button type="submit">Submit</button>
            <div class="alert" ng-if="contact.showAlert">
                Please <a href="/login">login</a>
            </div>
        </form>    
    </div>
</div>

JavaScript

angular.module('webApp', [])
.factory('Auth', function($http) {
    var currentUser = {};    
    return {
        login: function(credentials) {
            $http.post('/api/auth', credentials).then( function (data) {
                currentUser = data.user;
            });
        }, 
        logout: function() {
            currentUser = {};
        },
        isLoggedIn: function() {
            return !!currentUser.id;
        } 
    };
});

angular.module('webApp')
.controller('ContactCtrl', function(Auth) {
    this.showAlert = false;
    this.submitted = false;
    this.submitForm = function() {
        // If the user is not logged-in, return and display the alert.
        if (!Auth.isLoggedIn()) {
            this.showAlert = true;
            return;
        }
        // Handle form submit.
        this.submitted = true;     
    };   
});

angular.module('authMock', [])
.provider('Auth', function () {
    this.userLoggedIn = false;
    this.$get = function() {
      return  {
        login: function() {
          this.userLoggedIn = true;
        },
        logout: function() {
          this.userLoggedIn = false;
        },
        isLoggedIn: function() {
          return this.userLoggedIn;
        }
      };
    };
});

/**
 * Code specs
 */
describe('Controller: ContactCtrl', function () {
  // Load the controller's module.
  beforeEach(module('webApp'));
  // Load the mock service.
  beforeEach(module('authMock'));
    
  var ContactCtrl, auth;
  // Initialize the controller and the mocked service.
  beforeEach(inject(function ($controller, _Auth_) {
    auth = _Auth_;
    ContactCtrl = $controller('ContactCtrl', {
      Auth: auth
    });
  }));
    
  it('should submit the form if the user is logged in', function () {
    auth.login();
    ContactCtrl.submitForm();
    expect(ContactCtrl.submitted).toBe(true);
  });
    
  it('should not submit the form if the user is not logged in', function () {
    auth.logout();
   ...