1

I have this code in my controller:

angular.module('clientApp')
  .controller('UserSettingsAccountCtrl', function ($scope, userFactory) {

    $scope.$watch(function() {
      return userFactory.getUser();
    }, function(value) {
      $scope.user = value;
      console.log($scope.user) //defined when I add scope.$digest() in my test
      }
    });

    console.log($scope.user) //undefined
});

It's executed when my controller is instantiated. But in my test it's not. I get user undefined.

beforeEach(inject(function ($controller, $rootScope, userFactory) {
    scope = $rootScope.$new();
    var mockUser = {
      userId: 1,
      name: 'Per',
      premium:{
        active:false,
        freeTrial:{
          expired:{
            value:false
          }
        }
      }
    };
    userFactory.setUser(mockUser);
    console.log(userFactory.getUser()); //User is returned
    UserSettingsAccountCtrl = $controller('UserSettingsAccountCtrl', {
      $scope: scope,
    });
  }));

  it('should be ok to start a trial if the trial has not expired and the user is not a premium', function(){
    console.log(scope.user) //undefined
  ...
  });

Why is this executed when I run it live but not in my test?

Joe
  • 4,274
  • 32
  • 95
  • 175
  • Possible duplicate of [How would I test a $scope.watch (AngularJS) change in Jasmine?](http://stackoverflow.com/questions/17112446/how-would-i-test-a-scope-watch-angularjs-change-in-jasmine) – James Kingsbery Nov 19 '15 at 20:08

1 Answers1

5

Normally, the watch is triggered from a digest cycle, either at initialization time or as a result of some event. From tests, you need to run a digest cycle manually after changing something that should affect, or be affected by, the scope:

$scope.$digest();
Thomas
  • 174,939
  • 50
  • 355
  • 478
  • Probably in `beforeEach`, as the last line, just after you instantiated your controller. Could you post the relevant parts of your controller to make sure? – Thomas Oct 22 '14 at 15:04
  • Now I added the relevant parts. – Joe Oct 22 '14 at 15:31
  • Hmm, I think this should work. Does `scope` refer to the same variable in `beforeEach` as in `it`? I can't see where it is declared. If you set a breakpoint inside the watch, does it hit? – Thomas Oct 22 '14 at 15:37
  • Yes, other scopes works so it's the same (generated from yeoman). No, it does not hit the watch. – Joe Oct 22 '14 at 15:43
  • Does it _evaluate_ the watch, i.e. does it hit on the `userFactory.getUser()` line? – Thomas Oct 22 '14 at 15:46
  • I was to fast. It does hit when I add scope.$digest(). But it is still undefined outside the watch. I added two console.logs in my question. – Joe Oct 22 '14 at 15:54
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/63501/discussion-between-thomas-and-user1572526). – Thomas Oct 22 '14 at 15:59