【问题标题】:Jasmine spy doesn't work on a function defined in a constructorJasmine spy 不适用于构造函数中定义的函数
【发布时间】:2016-11-24 16:19:02
【问题描述】:

我想监视一个用作点击处理程序的函数。该函数在闭包的构造函数中定义。

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');

尽管 Jasmine 很高兴 'internalClickHandler' 存在并创建了间谍,但它永远不会被调用。事实上,原来的函数(internalClickHandler)被调用了。

我创建了examples in codepen.io 来显示问题。失败的测试是试图监视构造函数中的函数。

我的事件处理程序需要在构造函数中,因为它需要访问对象的实例,并且我确实想测试是否触发了正确的处理程序,而不仅仅是触发了点击事件。

任何帮助都会得到极大的欢迎。谢谢

【问题讨论】:

    标签: events constructor jasmine spy


    【解决方案1】:

    由于以下原因,您将无法执行该测试:

    1. 您的 clickHandler 实际上被重新分配给不同的变量 在 DOM 元素 onClick 上,看到这一行 document.getElementById('testLink').addEventListener('click', _this.internalClickHandler);
    2. 当点击触发器被调用时,它实际上执行了函数 onClick 而不是 internalClickHandler,尽管它们实际上是(代码方面) 相同,但它们被两个不同的变量引用 即onClick & internalClickHandler
    3. 你最好尝试这样的事情。

      it('should spy on a event binding defined in constructor', function() {
        var testViewModel = new viewModel();
        var tl = document.getElementById('testLink');
        var theSpy = spyOn(t1, 'onclick');
        //$('#testLink').trigger('click');
      
        var event = new MouseEvent('click', {
          'view': window,
          'bubbles': true,
          'cancelable': true
        });
      
        tl.dispatchEvent(event);
        expect(theSpy).toHaveBeenCalled();
        tearDown();
      });
      

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回复,您的建议会帮助我解决问题,希望也能帮助其他人。你是对的,onclick 函数被调用,而不是构造函数中的函数。但是,您的解决方案并不能帮助我创建有用的测试,因为我只知道 onclick 已被处理,但我不知道是什么处理了它。我已经发布了我的解决方案,它允许我监视构造函数中的函数。
    • 如果您认为此答案有助于理解模拟点击的概念/引导积极解决方案,那么点赞会有所帮助。
    【解决方案2】:

    我通过使用一个匿名函数作为处理程序来解决这个问题,该函数包装了对 internalClickHandler 的引用。这样,原始函数仍然会被调用,我可以监视它。

    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 
    }); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-27
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      相关资源
      最近更新 更多