【问题标题】:sinon.stub not stubbing original methodsinon.stub 不存根原始方法
【发布时间】:2023-03-15 13:35:01
【问题描述】:

在为我的以下代码 S3resizer 编写测试时,当我调用 testedModule 时,存根 S3getStub 似乎无法正常工作,我得到了 mocha AssertionError: expected stub to have been called at least once, but it was never called 的响应。

为什么S3resizer_get 没有被存根?

s3Handler:

'use strict';

var s3 = new (require('aws-sdk')).S3();

var S3Handler = {};

S3Handler._get = function (bucketName, imgName, callback) {

    var params = {
        Bucket: bucketName,
        Key: imgName
    };

    s3.getObject(params, function (error, data) {
        if (error) {
            console.log("Error, %s", error);
            callback(error, null);
        }
        console.log("good data");
        callback(null, data);
    });
};

module.exports = S3Handler;

S3resizer:

/**
 * This function is called when the protocol defined in index.js is "s3:".
*/

'use strict';

var async = require('async');
var S3 = require("./S3Handler");
var S3get = S3._get;
var S3put = S3._put;
var read = require("./readDirectory");
var readDirFile = read._get;
var readDirCont = read._getContent;
var rs = require("./resizer").resize;
var _sqs = require("./sqsHandler");
var sqsSend = _sqs._sendMessage;

var S3resizer = {};

S3resizer.rs = function (imgName, bucketName) {

S3get(bucketName, imgName, function (error, data) {console.log(data);});
};

module.exports = S3resizer;

tests:

var chai = require('chai');
var sinonChai = require("sinon-chai");
var expect = chai.expect;
var extend = require('lodash').extend;
var sinon = require('sinon');
chai.use(sinonChai);
var proxyquire = require('proxyquire').noPreserveCache();
var url = require('url');
var mockDir = require('mock-fs');

describe("S3resizer", function () {
    var testedModule, fakeResponse, fakeFiles, S3getStub, rsStub, readDirFileStub, readDirContStub, S3putStub, sqsCreateStub, sqsSendStub, cbSpy, callbSpy, imgName, bucketName, sizesObj, imageType, obj;

before(function () {

    S3getStub = sinon.stub();

    rsStub = sinon.stub();

    readDirContStub = sinon.stub();

    readDirFileStub = sinon.stub();

    S3putStub = sinon.stub();

    sqsCreateStub = sinon.stub();

    sqsSendStub = sinon.stub();

    cbSpy = sinon.spy();

    callbSpy = sinon.spy();

    testedModule = proxyquire('../S3resizer', {
        './S3Handler': {
            _get: S3getStub,
            _put: S3putStub
        },
        './readDirectory': {
            _get: readDirFileStub,
            _getContent: readDirContStub
        },
        './resizer': {
            resize: rsStub
        },
        './sqsHandler': {
            _sendMessage: sqsSendStub
        },
    });

    imgName = "Whatever";

    bucketName = "Chappie";

    sizesObj = [
        { width: 800, height: 800, name: 'large' },
        { width: 500, height: 500, name: 'medium' },
        { width: 200, height: 200, name: 'small' },
        { width: 45, height: 45, name: 'thumbnail'}
    ];

    imageType = "png";

    obj = {
        "event":"re-sized",
        "message": {
            "url":"S3://bucketname/images/908798",
            "sizes":["large","medium","small","thumbnail"]
        }
    };

    fakeResponse = {Body: 'image content'};

    fakeFiles = ["thumbnail_Whatever", "small_Whatever", "medium_Whatever", "large_Whatever"];



});

it("calls callback with message 'Done'", function () {
    S3getStub.callsArgWith(2, null, fakeResponse);

    testedModule.rs(imgName, bucketName);
    expect(S3getStub).has.been.called;  
});

});

【问题讨论】:

  • 尝试@noCallThru 看看是否会导致错误。这将证明 proxyquire 确实在模拟正确的模块。
  • @Sukima 它仍然调用原始函数。同样的错误。
  • 那么您已经证明 proxyquire 没有按预期工作。最好调试那个模块。
  • @Sukima 你能看出proxyquire 不能正常工作的原因吗?
  • 不,我什么都看不到。我确实知道我在 proxyquire 方面的经验非常紧张。我最近发现Mockery 的运气更好

标签: node.js unit-testing sinon


【解决方案1】:

来自the fine manual

因此,完全按照要求中的语句指定它 测试文件

您告诉 proxyquire 捕获 ./S3Handler 的 require,实际上 S3Resizer 正在加载 ./S3Handler.js(包括 .js)。这不完全一样。

【讨论】:

  • 我已经改变了这一点,正如你在我原来的问题中看到的那样。我还通过将调用从before hook 传递给测试模块来更改测试。但是它仍然没有对模块进行存根,并且仍然尝试调用实际的 S3 存储桶。
  • @hyprstack 我使用过类似的设置,效果很好。理想情况下,您应该将代码简化为仍然失败的最小示例。
  • 我已将我的代码缩减为一个最小示例并更新了我的问题。
  • @hyprstack here 是一个真正通过测试的最小示例。
  • 欣赏这个例子。我明白你的意思了。难道是我在我的S3Handler 中需要S3,这会导致proxyquire 跳闸?
【解决方案2】:

这行得通。为了避免使用缓存版本并重构代码以使用 require 模块的全局覆盖,我必须重新要求测试中的模块。

describe("S3resizer succesfull call", function () {

    // To avoid having to refactor code with a global override of the require method and using the cached versions from previous tests, freshly require the modules and inject in stubs.
    var S3 = require("../S3Handler");
    var read = require("../readDirectory");
    var _resizer= require("../resizer");
    var _sqs = require("../sqsHandler");

    var testedModule, fakeResponse, fakePutMessage, fakeSqsMessage, fakeFiles, S3getStub, rsStub, readDirFileStub, readDirContStub, S3putStub, sqsSendStub, cbSpy, callbSpy, imgName, bucketName, sizesObj, imageType, obj;

    before(function () {

        S3getStub = sinon.stub(S3, "_get");

        rsStub = sinon.stub(_resizer, "resize");

        readDirContStub = sinon.stub(read, "_getContent");

        readDirFileStub = sinon.stub(read, "_get");

        S3putStub = sinon.stub(S3, "_put");

        sqsSendStub = sinon.stub(_sqs, "_sendMessage");

        cbSpy = sinon.spy();

        callbSpy = sinon.spy();

        testedModule = proxyquire('../S3resizer', {
            './S3Handler': {
                _get: S3getStub,
                _put: S3putStub
            },
            './readDirectory': {
                _get: readDirFileStub,
                _getContent: readDirContStub
            },
            './resizer': {
                resize: rsStub
            },
            './sqsHandler': {
                _sendMessage: sqsSendStub
            }
        });

        imgName = "Whatever";

        bucketName = "Chappie";

        sizesObj = [
            { width: 800, height: 800, name: 'large' },
            { width: 500, height: 500, name: 'medium' },
            { width: 200, height: 200, name: 'small' },
            { width: 45, height: 45, name: 'thumbnail'}
        ];

        imageType = "png";

        obj = {
            "event":"re-sized",
            "message": {
                "url":"S3://bucketname/images/908798",
                "sizes":["large","medium","small","thumbnail"]
            }
        };

        fakeResponse = {Body: 'image content'};

        fakePutMessage = {messageId: "1223abc"};

        fakeSqsMessage = {BinaryValue: "123"};

        fakeFiles = ["thumbnail-Whatever", "small-Whatever", "medium-Whatever", "large-Whatever"];

        S3getStub.callsArgWith(2, null, fakeResponse);

        rsStub.callsArgWith(4, null);

        readDirFileStub.callsArgWith(1, null, fakeFiles);

        readDirContStub.callsArgWith(2, null, fakeResponse);

        S3putStub.callsArgWith(5, null, fakePutMessage);

        sqsSendStub.callsArgWith(1, null, fakeSqsMessage);

        testedModule.rs(imgName, bucketName, sizesObj, imageType, obj, function () {
            cbSpy.apply(null, arguments);
        });
    });

    after(function () {
        S3._get.restore();
        _resizer.resize.restore();
        read._getContent.restore();
        read._get.restore();
        S3._put.restore();
        _sqs._sendMessage.restore();
    });
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-02
    • 2011-02-02
    • 1970-01-01
    • 2013-08-03
    • 2017-04-27
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多