Search code examples
eventsconstructorjasminespy

Jasmine spy doesn't work on a function defined in a constructor


I want to spy on a function used as a click handler. The function is defined within the constructor of a closure.

var viewModel = function(){
  var viewModel = function(){
    var _this = this;
    _this.internalClickHandler = function(){
      console.log('I handled a click');
    }
  }
  return viewModel;
}();

var testViewModel = new viewModel();
var theSpy = spyOn(testViewModel, 'internalClickHandler');

Even though Jasmine is happy that 'internalClickHandler' exists and creates the spy, it never gets called. In fact the original function (internalClickHandler) gets call instead.

I've created examples in codepen.io that show the problem. The failing test is the one trying to spy on a function in the constructor.

My event handler needs to be in the constructor as it needs access to instance of the object and I do want to test that the correct handler has been fired not just that the click event was triggered.

Any help would be greatly received. Thanks


Solution

  • I resolved this by using as the handler an anonymous function wrapping a reference to internalClickHandler. This way the original function still gets called and I'm able to spy on it.

    var viewModel = function(){
      var viewModel = function(){
        var _this = this;
        _this.internalClickHandler = function(){
          console.log('I handled a click');
        }
      }
      return viewModel;
    }();
    
    var theViewModel = new viewModel();
    var theSpy = spyOn(testViewModel, 'internalClickHandler');
    
    $('#testLink').on('click', 
    function(){ 
        theViewModel.internalClickHandler(); //<-- The anonymous function calls internalClickHandler 
    });