4

I'm having some trouble adapting this test to use the "controller as" syntax. Here's what I have ...

The controller I'm testing is:

function MyCtrl ($scope, someService) {
  someService.get()
  .success(function(data){
    $scope.person = data;
  });
 }
angular.module('myApp')
.controller('MyCtrl', MyCtrl);

The unit test is:

beforeEach(module('myApp'));

  var scope,
    fakeService, 
    controller, 
    q, 
    deferred;

  beforeEach(function () {
      fakeService = {
          get: function () {
              deferred = q.defer();
              deferred.resolve({ "test": "data" });
              return deferred.promise;
          }
        };
      spyOn(fakeService, 'get').and.callThrough();
  });

  beforeEach(inject(function ($controller, $q, $rootScope) {
      q = $q;
      scope = $rootScope.$new();
      controller = $controller('MyCtrl as person', { $scope: scope, someService: fakeService });
  }));

  it('The person object is not defined yet', function () {
      expect(scope.person).not.toBeDefined();
  });

This test for scope.person fails with the error TypeError: undefined is not a function.

I've tried this solution where I've changed expect(scope.person) to expect(scope), but that returns TypeError: undefined is not a function.

I'm using AngularJS 1.2.22, Karma 0.12.21 and 0.2.2 of the karma-jamsine plugin.

Thanks in advance for whatever suggestions you have.

Community
  • 1
  • 1
jody tate
  • 1,406
  • 1
  • 13
  • 25

1 Answers1

0

Apart from the fakePwsService != fakeService that @JBNizet pointed out.

The promise that is created by $q.defer() doesn't have the success() method.

The .success() and .error() methods are special ones that added by $http service itself.

Therefore, if you would like to mock the someService this way, you have to also mimic the .success() yourself as well.

fakePwsService = {
  get: function () {
    deferred = q.defer();
    deferred.resolve({ "test": "data" });

    var promise = deferred.promise;

    promise.success = function(fn) {
      promise.then(function(response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    promise.error = function(fn) {
      promise.then(null, function(response) {
        fn(response.data, response.status, response.headers, config);
      });
      return promise;
    };

    return promise;
  }
};

The above code copied from http.js#L743.

PS. This problem isn't related to "controller as" syntax.

runTarm
  • 11,537
  • 1
  • 37
  • 37
  • Thanks for the note re: the "controller as" syntax. – jody tate Aug 14 '14 at 21:30
  • This answer works if I change `$controller('PwsCtrl as person', { $scope: scope, pwsService: fakePwsService })` to `$controller('PwsCtrl', { $scope: scope, pwsService: fakePwsService })`. Is it possible to run this test using the "as" syntax? – jody tate Aug 14 '14 at 21:41
  • Is there any error? May be it because your assert statement is incorrectly, it should be `expect(scope.person).toBeDefined();`. See this [plunker](http://plnkr.co/edit/01fvz43nodMlzEmgEIro?p=preview). – runTarm Aug 16 '14 at 08:33