Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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.

share|improve this question
2  
fakePwsService != fakeService –  JB Nizet 2 days ago
    
edited to fix the fakePwsService != fakeService typo –  jody tate 2 days ago

1 Answer 1

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.

share|improve this answer
    
Thanks for the note re: the "controller as" syntax. –  jody tate 2 days ago
    
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 2 days ago
    
Is there any error? May be it because your assert statement is incorrectly, it should be expect(scope.person).toBeDefined();. See this plunker. –  runTarm 15 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.