将 class 实例方法存根到 return 解析的 Promise(使用 Sinon)

Stub class instance method to return resolved Promise (using Sinon)

我正在为 Node Express 应用编写控制器单元测试。

控制器创建模型的一个实例 class,然后调用其方法之一 returns 已解决的 Promise。我需要对 class 构造函数进行存根,然后对方法进行存根,以便它 returns 一个使用测试数据解析的 Promise。

控制器:

const Model = require('../../models/model');

module.exports = function (req, res, next) {
    const instance = new Model(req.body);

    instance.method()
        .then(result => {
            // do something with result
        })
        .catch(err => next(err));
};

测试:

const proxyquire = require('proxyquire');
const sinon = require('sinon');
require('sinon-as-promised');

const Model = require('../../../../server/models/model');

const stubs = {
    model: sinon.stub(Model.prototype, 'method', function () { sinon.stub().resolves('foobar') })
};

const subject = proxyquire('../../../../server/controllers/models/method', {
    '../../models/model': stubs.model
});

Sinon.JS Documentation 存根 API 说:

var stub = sinon.stub(object, "method", func);

Replaces object.method with a func, wrapped in a spy.

但是当测试代码在控制器中命中 .then 时我得到这个错误:

instance.method(...).then is not a function

直接在存根上调用 .resolves()(来自 sinon-as-promised)将 then/catch/finally 方法提供给 class 实例 而不是而不是 class 实例方法 根据需要:

sinon.stub(Model.prototype, 'method').resolves('foobar')

在此先感谢您的帮助!

您需要从存根函数中 return sinon.stub().resolves('foobar')

const stubs = {
  model: sinon.stub(Model.prototype, 'method',
    function () { return sinon.stub().resolves('foobar') })
};

但你可能最好 return 使用原生 Promise,因为你没有保留对内部存根的引用:

const stubs = {
  model: sinon.stub(Model.prototype, 'method',
    function () { return Promise.resolve('foobar') })
};

已发现此解决方案,您可以在其中制作自己的假模型:

const proxyquire = require('proxyquire');
const sinon = require('sinon');
require('sinon-as-promised');

const methodStub = sinon.stub().resolves('foobar');

const ModelStub = function () {
    this.method = methodStub;
};

const subject = proxyquire('../../../../server/controllers/models/method', {
    '../../models/model': ModelStub
});

归功于 Darren Hurley