试图监视阵列(茉莉).原型方法导致堆栈溢出



这很奇怪。使用testem运行器和jasmine2并执行以下规范(尽管它正确地标记了没有期望):

describe('Spying on array.prototype methods', function(){
  it('should work this way', function(){
    spyOn( Array.prototype, 'push' ).and.callThrough();
    // expect(1).toBe(1);
  });
});

然而,添加一个expect(任何expect !),它会导致堆栈溢出,在testem控制台显示以下消息:RangeError: Maximum call stack size exceeded. at http://localhost:7357/testem/jasmine2.js, line 980 html报告页面达到规格,然后挂起而不显示任何实际结果。

最终我想做这样的事情:

describe('Some structure.method', function(){
  it('does not use native push', function(){
    spyOn( Array.prototype, 'push' ).and.callThrough();
    [].push(1); // actually more like `myStructure.myMethod('test')`
    expect( Array.prototype.push ).not.toHaveBeenCalled();
  });
});

提前感谢任何可以阐明这个奇怪的人。我可以不监视原生原型方法吗?

当您监视某个对象时,jasmine会创建一个包装器来跟踪该函数的调用。在这里,当你监视原型方法时,基本上即使是jasmine中的push操作本身也会调用监视而不是数组中的实际push方法,这会导致无限循环。

当你调用[].push(1)时,它实际上像下面这样调用跟踪器:

   spy = function() {
    callTracker.track({ //<-- Calls tracker to track invocation
      object: this,
      args: Array.prototype.slice.apply(arguments)
    });

依次调用调用跟踪器并将调用上下文推入其内部跟踪器数组,并进入递归循环,直到调用堆栈失效。

this.track = function(context) {
  calls.push(context); //Now this again calls the spy
};

相反,如果你监视数组实例上的方法,你就不会有这个问题,因为它为的push属性创建了一个监视包装器,数组实例(或者换句话说,由push持有的该实例的引用(当前继承自array原型)将被jasmine创建的监视的新函数引用覆盖):

it('does not use native push', function(){
  var arr = [];
  spyOn(arr, 'push' ).and.callThrough();
  arr.push(1);
  expect(arr.push).toHaveBeenCalledWith(1);
});

但是作为一个真实的用例(至少我从来没有),你总是可以检查目标数组的长度,并在一个特定的操作后得到最后一个项目进行比较。您可能永远不需要监视本机方法(至少不需要监视数组:)),而是针对您感兴趣的对象进行测试并监视那些目标方法。

相关内容

  • 没有找到相关文章

最新更新