【问题标题】:Stubbing and/or mocking a class in sinon.js?在 sinon.js 中存根和/或模拟一个类?
【发布时间】:2012-09-30 22:02:22
【问题描述】:

我为我的应用程序创建了一个数据库包装器,如下所示。为了测试它,我显然想替换实际的数据库库。我可以创建一个模拟 query 方法的新类并在那里捕获所有输入,但使用 sinon.js 似乎更合适,但我将如何使用它?
我应该使用sinon.jsmockstub 功能吗?

wrapper = (function() {

  function wrapper() {}

  wrapper.db = require("database");

  wrapper.prototype.insertUser = function(doc) {
    return this.db.query("INSERT INTO USERS...");
  };

  return wrapper;

})();

【问题讨论】:

    标签: javascript node.js sinon


    【解决方案1】:

    你可以同时使用。

    Mock 有一个预期的有序行为,如果没有正确遵循,将会给你一个错误。

    Stub 类似于模拟,但没有顺序,因此您可以按照自己的方式调用方法。 根据我的经验,您几乎不需要模拟。

    它们都将用你的方法替换一个空方法,或者如果你通过了一个闭包。 应该是这样的:

    stub = sinon.stub(wrapper , 'insertUser ', function () { return true; });
    

    然后添加期望行为来检查它是否确实发生了。

    我喜欢使用JasmineJasmine-Sinon 来检查测试。

    【讨论】:

    • 哦。所以最好存根 insertUser 方法而不是 insertUser 所做的 this.db-call?
    • 取决于您要测试的内容,但是如果您想测试 insertUser 是否插入到数据库中,这将是一个集成测试,并且没有存根可以让您免于使用内存中的一些真实逻辑例如,数据库“伪造”Oracle,如果您想测试是否在需要时调用了 insertUser,那么存根 insertUser 方法可能是一种方法......
    • 从 3.0 开始,这将是 stub = sinon.stub(wrapper , 'insertUser ').callsFake( function () { return true; });
    • stub(obj, 'meth', fn) 已被移除,请参阅文档
    【解决方案2】:

    首先,我会稍微修改一下您的类定义(大写类名并修复数据库分配):

    var Wrapper = (function() {
    
      function Wrapper() {
        this.db = require("database");
      }
    
      Wrapper.prototype.insertUser = function(doc) {
        return this.db.query("INSERT INTO USERS...");
      };
    
      return Wrapper;
    
    })();
    

    存根整个班级:

    var WrapperStub = sinon.spy(function() {
      return sinon.createStubInstance(Wrapper);
    });
    

    sinon.createStubInstance 将创建一个 Wrapper 实例,其中每个方法都是一个存根。 sinon.spy 将允许我们监视类实例化。

    所以你可以这样锻炼:

    // verify instantiation
    var wrapper = new WrapperStub();
    expect(WrapperStub).to.have.been.calledWithNew;
    
    // verify method stub
    wrapper.insertUser.returns('data');
    expect(wrapper.insertUser()).to.equal('data');
    expect(wrapper.insertUser).to.have.been.calledOnce;
    

    (断言使用chaisinon-chai

    我只是说“练习一下”,因为这段代码 sn-p 不是实际的单元测试。实例化和方法调用将由您的测试对象进行。

    现在,如果你想模拟一个由 require() 注入的依赖项——比如你的例子中的db = require('database')——你可以尝试像Jest(但不使用sinon)或sinonquire这样的测试工具。我的创作灵感来自 Jest,但要与 sinon 以及您最喜欢的测试工具(我的是 mocha)一起使用。在内部,sinonquire 使用与上述相同的技术,将 sinon.spysinon.createStubInstance 组合到一个类中。

    猜你喜欢
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 2018-03-06
    • 2014-01-31
    • 2017-03-02
    • 1970-01-01
    相关资源
    最近更新 更多