Stubbing and/or mocking a class in sinon.js?

后端 未结 2 1480
心在旅途
心在旅途 2021-02-07 07:27

I\'ve created a database wrapper for my application, shown below. To test it, I obviously would like to replace the actual database library. I could create a new class that mock

2条回答
  •  忘了有多久
    2021-02-07 07:38

    First, I'd modify your class definition a bit (uppercase class name and fix db assignment):

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

    To stub the whole class:

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

    sinon.createStubInstance will create an instance of Wrapper where every method is a stub. sinon.spy will allow us to spy the class instantiation.

    So you could exercise it like this:

    // 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;
    

    (assertions use chai and sinon-chai)

    I said just "exercise it" because this code snippet is not an actual unit test. Instantiation and method calls will be made by your subject under test.

    Now, if you want to mock a dependency injected by require() –such as db = require('database') in your example–, you could try a testing tool like either Jest (but not using sinon) or sinonquire which I created inspired by Jest but to use it with sinon plus your favorite testing tool (mine is mocha). Internally, sinonquire uses the same technique shown above of combining sinon.spyand sinon.createStubInstance to stub a class.

提交回复
热议问题