简体   繁体   中英

Mocha / Sinon Unit test JS Class and Instance issue

I'm trying to unit test some express middleware which has dependencies on some classes I've made.

Middleware.js

const MyClass = require('../../lib/MyClass');

const myClassInstance = new MyClass();

    function someMiddleware(req, res) {
        myClassInstance.get().then(function(resp) {
          res.render('somefile.html');
        });
    };

Test.js

const MyClass = require('../../lib/MyClass');
const sinon = require('sinon');
const chai = require('chai');
const expect = chai.expect;

// File we are testing
const someMiddleware = require('path/to/middleware');

MyClassMock = sinon.spy(function() {
    return sinon.createStubInstance(MyClassMock);
});
describe('My Middleware', function() {

    let renderSpy, classStub;
    let res = {
        render: function() {}
    }

    beforeEach(function() {
        renderSpy = sinon.stub(res, 'render');
    })

    afterEach(function() {
        renderSpy.restore();
    })

    it('should call render function', function() {

        someMiddleware.someMiddleware(req, res);
        expect(renderSpy.calledOnce);

    });
});

I have tried a bunch of things however I can't quite seem to actually mock this class and mock the instance created! when it runs it will try to run the actual class with it's related dependencies inside.

Cheers folks!

Your Intent: replace/stub the dependencies of your middleware.

Your problem: this isn't possible from the outside of your module. You somehow need to "intercept" which code will be used.

There are two options, both of which I have written at length about in other places ( 1 , 2 , 3 ), so I'll do the shortform here:

Manual dependency injection

In your middleware module, provide a __setMyClassInstance(stubbedInstance) method that is only called from tests.

  • Pro: very easy, no frameworks needed
  • Con: test-only code that opens up your module

Link seams

This is about replacing require() calls in your code with another module loader that returns objects of your liking. In your test code:

const myMiddleware = proxyquire('../../src/middleware', { '../../lib/MyClass': myStubbedInstance })
  • Pro: Achieves the same as DI, but requires no code changes in the module
  • Con: not as clear cut what is going on, requires learning a new dependency

If you are stuck after looking at these very brief explanations, I suggest looking at my provided links for long-form explanations and links to tutorials on Link Seam libraries such as proxyquire and rewire .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM