0

I have a service that synchronously returns data to a controller:

angular.module('app').controller(function($scope, myService) {
  $scope.foo = myService.getFoo();
});

This works just fine in the browser. In my unit tests, $scope.foo is undefined:

beforeEach(function () {
  module('app');
  myService = jasmine.createSpyObj('myService', ['getFoo']);

  inject(function($controller, $rootScope) {
    $scope = $rootScope.$new();
    ctrl = $controller('ModelSliderCtrl', {
      myService: myService,
      $scope: $scope
    });
  });
});

it('should have foo on the scope', function() {
  myService.getFoo.and.returnValue({});

  expect(myService.getFoo).toHaveBeenCalled();  // PASS
  $scope.$digest();
  expect($scope.foo).toBeDefined();  // FAIL - $scope.foo is undefined
});

This does work in both the browser and tests:

angular.module('app').controller(function($scope, myService) {
  $scope.init = function() {
    $scope.foo = myService.getFoo();
  };

  $scope.init();
});

.

it('should have foo on the scope', function() {
  myService.getFoo.and.returnValue({});

  $scope.init();
  expect(myService.getFoo).toHaveBeenCalled();  // PASS
  expect($scope.foo).toBeDefined();  // PASS
});

I'd like to believe I'm fairly well-versed in Angular, Jasmine and JavaScript. I've also asked some colleagues who are equally puzzled.

Can anyone explain to me what is going on here?

2
  • What is the type of foo? is it a promise? Commented May 28, 2014 at 22:02
  • No, you can see it's being mocked to return a plain object. Commented May 28, 2014 at 22:05

1 Answer 1

1

You are setting up a mock

it('should have foo on the scope', function() {
  myService.getFoo.and.returnValue({});

after your controller has been instantiated. It's too late to set up the mock by then, do it before instantiating your controller since you are executing init() right away.

  myService = jasmine.createSpyObj('myService', ['getFoo']);
  myService.getFoo.and.returnValue({});

  inject(function($controller, $rootScope) {
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.