Best way to test a controller with a Service injected using Jasmine

87 views
Skip to first unread message

Javier Hertfelder

unread,
Apr 7, 2013, 3:01:07 PM4/7/13
to ang...@googlegroups.com
Hi, 

I am trying to test a controller that inserts a book using Parse Baas Service, I am new in angularjs and I have been reading some documents and blogs of how to test using jasmine.

I know that I have several options but I have chosen to use jasmine spy, but I cannot make it run: 

My first question is: Is using Jasmine Spies the best way to test Services? I have also readed that angular provides $httpBackend for unit test services but I don't see how to fit this into my example..

Second question is why my test is not working?? 

BookCrossingApp.controller('AddBookCtrl', function ($scope, DataService, $location) {

    $scope.registerNewBook = function (book) {
        DataService.registerBook(book, function (isResult, result) {
            //How do I change to another view now?!!? Locate ?? 
            $scope.$apply(function () {
                $scope.registerResult = isResult ? "Success" : result;
            });
            if (isResult) {
                //$scope.registerResult = "Success";
                $location.path('/main');
            }
            else {
                $scope.registerResult = "Fail!";
                //$location.path('/');
            }

        });
    };

    DataService.GetBookRegistrationId(function (isResult, result) {
        $scope.$apply(function () {
            $scope.registrationCode = isResult ? $scope.book = { RegistrationId: result } : "Error: Retriving New Book Code";


        });
    });
});

My Parse service like this:

angular.module('DataServices', [])

/**
 * Parse Service
 * Use Parse.com as a back-end for the application.
 */
    .factory('ParseService', function () {
.....
registerBook: function registerBook(bookk, callback) {

                var book = new Book();

                book.set("title", bookk.title);
                book.set("description", bookk.Description);
                book.set("registrationId", bookk.RegistrationId);
                var newAcl = new Parse.ACL(Parse.User.current());
                newAcl.setPublicReadAccess(true);
                book.setACL(newAcl);

                book.save(null, {
                    success: function (book) {
                        // The object was saved successfully.
                        callback(true, null);
                    },
                    error: function (book, error) {
                        // The save failed.
                        // error is a Parse.Error with an error code and description.
                        callback(false, error);
                    }
                });
            },

and my test:

describe('Controller: AddBookCtrl', function() {

//  // load the controller's module
  beforeEach(module('BookCrossingApp'));


  var AddBookCtrl, scope, book;

  // Initialize the controller and a mock scope
  beforeEach(inject(function($controller, $rootScope, DataService) {
    scope = $rootScope;
    book = {title: "fooTitle13"};

    AddBookCtrl = $controller('AddBookCtrl', {
      $scope: scope, DataService: DataService
    });
  }));

    it('should call Parse Service method', function () {      
     
        //We need to get the injector from angular
        var $injector = angular.injector([ 'DataServices' ]);
        //We get the service from the injector that we have called
        var mockService = $injector.get( 'ParseService' );
        mockService.registerBook = jasmine.createSpy("registerBook");
        scope.registerNewBook(book);
        //With this call we SPY the method registerBook of our mockservice
        //we have to make sure that the register book have been called after the call of our Controller
        expect(mockService.registerBook).toHaveBeenCalled();
    });
    
});

Reply all
Reply to author
Forward
0 new messages