Mocha / Sinon 单元测试 JS Class 和实例问题

Mocha / Sinon Unit test JS Class and Instance issue

我正在尝试对某些 express 中间件进行单元测试,这些中间件依赖于我制作的某些 classes。

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

    });
});

我已经尝试了很多东西,但是我似乎无法真正模拟这个 class 并模拟创建的实例!当它 运行 时,它将尝试 运行 实际的 class 及其内部的相关依赖项。

大家好!

您的意图: replace/stub 您的中间件的依赖项。

您的问题:从您模块的外部这是不可能的。您不知何故需要 "intercept" 将使用哪个代码。

有两个选项,我在其他地方详细写过这两个选项(, , 3),所以我在这里做简写:

手动依赖注入

在您的中间件模块中,提供一个仅在测试中调用的 __setMyClassInstance(stubbedInstance) 方法。

  • Pro:非常简单,不需要框架
  • 缺点:test-only 打开模块的代码

Link接缝

这是关于用 returns 您喜欢的对象的另一个模块加载器替换您代码中的 require() 调用。在您的测试代码中:

const myMiddleware = proxyquire('../../src/middleware', { '../../lib/MyClass': myStubbedInstance })
  • Pro:实现与DI相同,但无需修改模块中的代码
  • 缺点:不清楚发生了什么,需要学习新的依赖项

如果您在看完这些非常简短的解释后仍感到困惑,我建议您查看我提供的 long-form 解释链接和 Link Seam 库教程的链接,例如 proxyquirerewire.