如何使用 sinon 存根/模拟从“超类”复制的依赖项方法

Posted

技术标签:

【中文标题】如何使用 sinon 存根/模拟从“超类”复制的依赖项方法【英文标题】:How do I stub/mock a dependency's method copied from "superclass" with sinon 【发布时间】:2015-01-11 13:35:21 【问题描述】:

我在测试一个不断变化的 Store 时遇到了问题,我想删除调度程序。我已经看到jest 是如何实现的,但我想用 sinon 实现同样的效果。

这就是我所拥有的

来源

lib/Dispatcher。完整代码here

var invariant = require('./invariant');

//...

function Dispatcher() 
  this.$Dispatcher_callbacks = ;


Dispatcher.prototype.register=function(callback) 
  var id = _prefix + _lastID++;
  this.$Dispatcher_callbacks[id] = callback;
  return id;
;


// ...

module.exports = Dispatcher;

调度员

module.exports.Dispatcher = require('./lib/Dispatcher')

AppDispatcher

var Dispatcher = require('flux').Dispatcher;
var copyProperties = require('react/lib/copyProperties');
var AppDispatcher = copyProperties(new Dispatcher(), 

  handleViewAction: function(action) 
    this.dispatch(
      source: 'VIEW_ACTION',
      action: action
    );
  

);

module.exports = AppDispatcher;

ItemStore我要测试的那个

var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var ItemConstants = require('../constants/ItemConstants');
var merge = require('react/lib/merge');

var CHANGE_EVENT = 'change';

var _items = [];

var ItemStore = merge(EventEmitter.prototype, 

  getSoekeresultat: function() 
    return _items;
  ,

  emitChange: function() 
    this.emit(CHANGE_EVENT);
  
);

AppDispatcher.register(function(payload) 
  var action = payload.action;

  switch(action.actionType) 
    case ItemConstants.ITEMS_FETCHED:
      _items = action.payload;
      ItemStore.emitChange();
      break;
    default:
  

  return true; // No errors.  Needed by promise in Dispatcher.
);

module.exports = ItemStore;

所以我想要存根的是 AppDispatcher.register。我该怎么做?

我尝试了几种方法,最后一次尝试是这样的:

var sinon = require("sinon");
require("jasmine-sinon");

describe("ItemStore", function()
  var AppDispatcher = require('js/dispatcher/AppDispatcher.js');
  sinon.stub(AppDispatcher, 'register', function () 
    console.log("stub");
  );
  it("should use stub when called directly", function()
    AppDispatcher.register(function (payload) 
    );
    //outputs "stub"
  );
  it("should use stub when requiring itemstore", function()
    var ItemStore = require('js/stores/ItemStore.js');
  // doesn't output "stub"
  );

);

谁能告诉我如何存根?

【问题讨论】:

【参考方案1】:

虽然它没有严格回答您的问题,但您可以使用proxyquire 来实现您想要实现的目标。它允许您在ItemStore 中存根AppDispatcherrequired。例如

var proxyquire = require('proxyquire');
var AppDispatcher = require('js/dispatcher/AppDispatcher.js');
var StubbedAppDispatcher = sinon.stub(AppDispatcher)

/*
 * This will load the `ItemStore` module, satisfying it's `AppDispatcher`
 * dependency (the `require('../dispatcher/AppDispatcher')` statement)
 * with our stubbed version.
 */
var ItemStore = proxyquire('js/stores/ItemStore.js', 
  '../dispatcher/AppDispatcher': StubbedAppDispatcher
);

【讨论】:

以上是关于如何使用 sinon 存根/模拟从“超类”复制的依赖项方法的主要内容,如果未能解决你的问题,请参考以下文章

轻松清理 sinon 存根

如何使用 sinon 存根 new Date()?

如何正确指定使用 ts-sinon 的模拟的两种类型?

如何使用 Sinon 存根 npm 包 `phin`

使用 sinon 为 redux 操作存根闭包函数

需要帮助在 NodeJS 中使用 Sinon 存根异步 / 等待承诺