【问题标题】:SinonJS calledOnce or callCount issue for a inner object function内部对象函数的SinonJS调用一次或调用计数问题
【发布时间】:2017-08-28 19:39:25
【问题描述】:

使用 SinonJS 3 运行测试我面临以下问题

测试有什么问题?

var creator = (function() {

  var createIfNotExists = function createIfNotExists() {
    _doCreate();
  };

  var _doCreate = function _doCreate() {
    console.log('_doCreate was called');
  };

  return {
    createIfNotExists:createIfNotExists,
    _doCreate:_doCreate
  };
}());

var util = {
  createIfNotExists:creator.createIfNotExists,
  _doCreate:creator._doCreate
};

var spyRequester = sinon.spy(util, '_doCreate');
util.createIfNotExists();

console.log(spyRequester.callCount); // prints 0 (should be 

线console.log(spyRequester.callCount); 应该打印 1 但它打印 0

https://codepen.io/thiagoh/pen/XaxBjr?editors=1011

【问题讨论】:

    标签: javascript unit-testing testing sinon


    【解决方案1】:

    您当前的createIfNotExists 实现正在调用在其范围内捕获的_doCreate。如果你想让它运行你的模拟,你应该以某种方式使这个函数之间的“链接”动态化。在您的特定情况下,使用 this._doCreate 应该可以工作。但是,如果使用不正确的上下文调用它会使您的 createIfNotExists 失败。

    var creator = (function() {
    
      var createIfNotExists = function createIfNotExists() {
        // pick _doCreate from the context or use default.
        (this._doCreate || _doCreate)();
      };
    
      var _doCreate = function _doCreate() {
        console.log('_doCreate was called');
      };
    
      return {
        createIfNotExists:createIfNotExists,
        _doCreate:_doCreate
      };
    }());
    
    var util = {
      createIfNotExists:creator.createIfNotExists,
      _doCreate:creator._doCreate
    };
    
    var spyRequester = sinon.spy(util, '_doCreate');
    util.createIfNotExists();
    
    console.log(spyRequester.callCount); // prints 1
    <script src="https://unpkg.com/sinon@3.2.1/pkg/sinon-3.2.1.js"></script>

    【讨论】:

    • 嘿@yuri,我发现这会起作用。问题是,SinonJS 怎么看不到我的外部函数正在调用这个函数? SinonJS 不能监视闭包/私有函数吗?我想知道为什么?
    • "SinonJS 不能窥探闭包/私有函数吗?"它不能。闭包中捕获的私有函数是真正私有的。除非作者提供了访问它们的方法,否则外部代码无法访问它们。如果你想监视私有函数,你需要更高级的东西(检查和修改源代码)。例如rewire
    • 我完全理解其中的原因,但我已将其公开,正如您在返回对象 _doCreate: _doCreate 中看到的那样。那么,SinonJS 怎么看不到呢?它实际上看到了函数,但没有看到 createIfNotExists_doCreate 之间的链接
    • 你已经创建了全新的对象。使 sinon 监视其功能之一(即用记录所有调用的间谍替换此新对象中的初始功能)。但是您的 createIfNotExists 仍然使用范围内捕获的原始函数。它不知道有另一个对象有一些 _doCreate 属性已被间谍替换。这不是 sinon 的限制,而是您实现 createIfNotExists 函数的方式。
    • 是的..你是对的。我以为是这些原因,但我无法接受。我个人不喜欢对 (this._doCreate || _doCreate)(); 等函数的后备绑定调用,但我没有看到其他方法可以让 Sinon 正确地监视我的对象..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 2022-10-07
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多