showcase: app.cars, testing $modal and promises
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 30 Aug 2015 01:23:46 +0000 (03:23 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 30 Aug 2015 01:23:46 +0000 (03:23 +0200)
angularjs/showcase/src/showcase/app/cars/cars-error-modal.controller.js
angularjs/showcase/src/showcase/app/cars/cars.controller.js
angularjs/showcase/src/showcase/app/cars/cars.controller.spec.js

index c0fd641..2f6456a 100644 (file)
     vm.ok = function () {
       var isAllowedEvent = $modalInstance.close(vm.selected.car);
       console.log('close: broadcasted event to the modal scope before the modal closes. ' +
-        'Was it allowed?' + isAllowedEvent);
+        'Was it allowed? ' + isAllowedEvent);
     };
 
     vm.cancel = function () {
       var isAllowedEvent = $modalInstance.dismiss('cancel');
       console.log('dismiss: broadcasted event to the modal scope before the modal closes. ' +
-        'Was it allowed?' + isAllowedEvent);
+        'Was it allowed? ' + isAllowedEvent);
     };
   }
 
index def4d7d..7cc5793 100644 (file)
   /* @ngInject */
   function Cars($modal, $timeout, cars) {
     var vm = this;
+
     vm.example = {
       text: 'try to send data',
       word: /^\s*\w*\s*$/,
       singleModel: 1
     };
-    vm.getCars = getCars;
-
-    function getCars() {
+    vm.getCars = function () {
       // ES6 way. success and error are deprecated because they are not following the ES6 way.
       cars.getAll().then(
         // Success
         // Error
         function(reason) {
           console.log('Cars controller error: ' + reason);
-          doModal('lg');
+          vm.doModal('lg');
         }
       );
-    }
+    };
 
-    function doModal(size) {
+    // How to test "private" methods in controllers?
+    // Two options:
+    // a) Extracting the logic of the "private" method to some service. The service could be
+    //    called ModalService and it could be used by any module. Does that ring a bell? :D
+    // b) The one I am using here. Attaching to vm/this because AngularJS is performing new MyController().
+    vm.doModal = function (size) {
       var cars = ['car1', 'car2', 'car3'];
       var modalInstance = $modal.open({
         animation: true,
         console.log('dismissed by tiemout at: ' + new Date());
         modalInstance.dismiss('dismissed by tiemout');
       }, 10000);
-    }
+    };
   }
 
 })();
index d04427b..f307cf0 100644 (file)
@@ -1,13 +1,16 @@
 describe('app.cars', function() {
   'use strict';
 
-  var Cars;
+  var isSuccessCallBack = true;
+  var onFulfilledValue = 'car1';
+  var onRejectedValue = 'error';
   // Why the heck do I need this stupid object if it is going to be spied by means of Jasmine?
   var cars = {
     getAll: function() {
       return {};
     }
   };
+  var Cars;
   var $q;
 
   beforeEach(function() {
@@ -25,17 +28,25 @@ describe('app.cars', function() {
 
   describe('Cars controller', function () {
 
-    it('should invoke GET all cars in service: old fashionable way', function () {
+    it('should invoke GET all cars in service with success: old fashionable way', function () {
 
       spyOn(cars, 'getAll')
         .and.callFake(function() {
-          var deferred = $q.defer();
-          return deferred.promise;
+          return {
+            then: function (successCallback, errorCallback) {
+              if (isSuccessCallBack) {
+                successCallback(onFulfilledValue);
+              } else {
+                errorCallback(onRejectedValue);
+              }
+            }
+          };
         });
 
       Cars.getCars();
 
       expect(cars.getAll).toHaveBeenCalled();
+      expect(Cars.cars).toEqual(onFulfilledValue);
     });
   });
 
@@ -44,15 +55,25 @@ describe('app.cars', function() {
 describe('app.cars', function() {
   'use strict';
 
-  var Cars;
+  var isSuccessCallBack = true;
+  var onFulfilledValue = 'car1';
+  var onRejectedValue = 'error';
   // With object already implementing the required spy :)
   var cars = {
-    getAll: jasmine.createSpy('cars.getAll').and.callFake(function() {
-      return $q(function(resolve) {
-        resolve();
-      });
-    })
+    getAll: jasmine.createSpy('cars.getAll')
+      .and.callFake(function() {
+        return {
+          then: function (successCallback, errorCallback) {
+            if (isSuccessCallBack) {
+              successCallback(onFulfilledValue);
+            } else {
+              errorCallback(onRejectedValue);
+            }
+          }
+        };
+      })
   };
+  var Cars;
   var $q;
 
   beforeEach(function() {
@@ -70,12 +91,28 @@ describe('app.cars', function() {
 
   describe('Cars controller', function () {
 
-    it('should invoke GET all cars in service: alternative way', function () {
+    it('should invoke GET all cars in service with success: alternative way', function () {
 
       Cars.getCars();
 
       expect(cars.getAll).toHaveBeenCalled();
+      expect(Cars.cars).toEqual(onFulfilledValue);
     });
+
+    it('should invoke GET all cars in service with error: alternative way', function () {
+
+      isSuccessCallBack = false;
+      spyOn(Cars, 'doModal')
+        .and.callFake(function() {
+          return {};
+        });
+
+      Cars.getCars();
+
+      expect(cars.getAll).toHaveBeenCalled();
+      expect(Cars.doModal).toHaveBeenCalled();
+    });
+
   });
 
 });