【问题标题】:sinon stub calls fake calling actual functionsinon stub 调用假调用实际函数
【发布时间】:2021-09-04 11:31:58
【问题描述】:

我有一种情况,我想为一个函数编写单元测试用例,以确保它是否工作正常。因此,我为该特定函数创建了存根,当我尝试调用假存根时,该函数实际上被调用而不是假调用。以下是我的场景:

  • 我有一个 main 函数,我从中调用函数 saveData(**)。
  • saveData(**) 函数正在调用 AWS SQS 以将消息保存到 DB

下面是我的主要功能:

'use strict';
async function mainFunction() {
  try {
    await saveData(
      name,
      age,
    );
    return true;
  } catch (e) {
    console.log('Error - [%s]', e);
    return null;
  }
}    
module.exports = { mainFunction };

下面是我的 saveData(**) 函数:

'use strict';
const AWS = require('aws-sdk');
const sqs = new AWS.SQS();
const saveData = async (
  name,
  age,
) => {
    await sendMessage(JSON.stringify(dbData));
    const params = {
        DelaySeconds: <some_delay>,
        MessageAttributes: <messageAttributes>,
        MessageBody: {name:name, age:age},
        QueueUrl: <URL_FOR_QUEUE>,
      };
      return sqs.sendMessage(params).promise();
  return true;
};
module.exports = {
  saveData,
};

我的测试用例是,

'use strict';

const express = require('express');
const bodyParser = require('body-parser');
require('app-module-path').addPath('./src');
const sinon = require('sinon');
const app = express();
const sqsSender = require('lib/queue');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const main = require('../../../src/main-function');
const routes = require('routes');
routes.configure(app);
let mainFunctionStub;
let saveDataStub;

describe('/v1/main', () => {
  beforeEach(() => {
    mainFunctionStub = sinon.stub(main, 'mainFunction');
    saveDataStub = sinon.stub(sqsSender, 'saveData');
  });
  describe('Test', () => {
    it(`should return success`, (done) => {
      const name = 'Name';
      const age = 'Age';
      saveDataStub.resolves({
        name,
        age,
      });
    });
  });

  afterEach(() => {
    mainFunctionStub.restore();
    mainFunctionStub.reset();

    saveDataStub.restore();
    saveDataStub.reset();
  });
});

但是这个测试又回来了,

error: Jun-20-2021 20:07:05:    Error - [Error [ConfigError]: Missing region in config

和,

Error: Timeout of 3500ms exceeded.

从这个错误中我可以说这实际上是在调用 SQS 函数而不是伪造。我怎样才能解决这个问题,或者我怎样才能假装调用这个函数?我是这个单元测试的新手,所以会有任何帮助。

【问题讨论】:

  • 你想测试什么? mainFunction 或 saveData?
  • 我想测试这两个功能的结合。例如。我想检查是否从 mainFunction 调用 saveData

标签: node.js unit-testing sinon stubbing sinon-chai


【解决方案1】:

存根通过替换导出对象的属性来工作。由于require 发生在 sinon 替换函数之前,因此您捕获对原始函数的引用,而不是动态使用当前设置的函数。

你没有在主文件中显示你的require 调用,但是从调用站点我推断你正在像const { saveData } = require('../foo/sqsSender') 一样导入它。这意味着您在第一次加载代码时会从对象中获取函数。如果您改为保留对sqsSender 模块 的引用,并在调用时引用该函数,则存根应该可以工作。

'use strict';
// Don't destructure / grab the function.
const sqsSender = require("../foo/sqsSender")+

async function mainFunction() {
  try {
    // Use reference through module
    await sqsSender.saveData(
      name,
      age,
    );
    return true;
  } catch (e) {
    console.log('Error - [%s]', e);
    return null;
  }
}

module.exports = { mainFunction };

【讨论】:

    猜你喜欢
    • 2020-05-23
    • 2019-11-24
    • 2019-07-17
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    相关资源
    最近更新 更多