如何在另一个函数nodejs中模拟一个函数

How to mock a function in another function nodejs

正在尝试为 /utility/sqsThing.js 中的以下模块编写单元测试。但是我很难模拟 sqs.sendMessage 方法。任何人都知道我应该怎么做。我正在使用 sinon 库和 mocha 进行 运行 测试。

我要单元测试的函数 utility/sqsThing.js:

const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });
const sqs = new AWS.SQS({ apiVersion: '2012-11-05' });
const outputQueURL = 'https:awsUrl';

const SQSOutputSender = (results) => {
  const params = {
    MessageBody: JSON.stringify(results),
    QueueUrl: outputQueURL,
  };
  // Method that I want to mock
  sqs.sendMessage(params, function (err, data) {
    if (err) {
      console.log('Error');
    } else {
      console.log('Success', data.MessageId);
    }
  });
};

我在单元测试中模拟 sqs.sendMessage 方法的尝试 sqsThingTest.js:

const sqsOutputResultSender = require('../utility/sqsThing');
const AWS = require('aws-sdk');
const sqs = new AWS.SQS({ apiVersion: '2012-11-05' });

const mochaccino = require('mochaccino');

const { expect } = mochaccino;
const sinon = require('sinon');


describe('SQS thing test', function() {
    beforeEach(function () {
        sinon.stub(sqs, 'sendMessage').callsFake( function() { return 'test' });
    });

    afterEach(function () {
        sqs.sendMessage.restore();
    });

  it('sqsOutputResultSender.SQSOutputSender', function() {
    // Where the mock substitution should occur
    const a = sqsOutputResultSender.SQSOutputSender('a');
    expect(a).toEqual('test');
  })
});

运行 这个单元测试 mocha tests/unit/sqsThingTest.js 但是我得到: AssertionError: expected undefined to deeply equal 'test'info: Error AccessDenied: Access to the resource https://sqs.us-east-1.amazonaws.com/ is denied.

看起来 mock 没有替换 aws api 调用。有人知道我如何在测试中模拟 sqs.SendMessage 吗?

尝试在 sendmessage 函数

存根后移动 sqsOutputResultSender 的声明
    var sqsOutputResultSender;
    const AWS = require('aws-sdk');
    const sqs = new AWS.SQS({ apiVersion: '2012-11-05' });

    const mochaccino = require('mochaccino');

    const { expect } = mochaccino;
    const sinon = require('sinon');


    describe('SQS thing test', function() {
        beforeEach(function () {
            sinon.stub(sqs, 'sendMessage').callsFake( function() { return 'test' });
            sqsOutputResultSender = require('../utility/sqsThing');
        });

        afterEach(function () {
            sqs.sendMessage.restore();
        });

      it('sqsOutputResultSender.SQSOutputSender', function() {
        // Where the mock substitution should occur
        const a = sqsOutputResultSender.SQSOutputSender('a');
        expect(a).toEqual('test');
      })
    });

您可以使用 rewire js 它是一个库,可让您将模拟属性注入要测试的模块。

你的要求声明看起来像这样:

var rewire = require("rewire");
var sqsOutputResultSender = rewire('../utility/sqsThing');

Rewire 将允许您模拟 sqsThing.js 文件顶级范围内的所有内容。

您还需要 return sqs.sendMessage 的值,这将解决问题 expected undefined to deeply equal 'test'

您的原始文件看起来与 return 语句一样。

//utility/sqsThing.js
const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });
const sqs = new AWS.SQS({ apiVersion: '2012-11-05' });
const outputQueURL = 'https:awsUrl';

const SQSOutputSender = (results) => {
  const params = {
    MessageBody: JSON.stringify(results),
    QueueUrl: outputQueURL,
  };
  // Method that I want to mock
  return sqs.sendMessage(params, function (err, data) {
    if (err) {
      console.log('Error');
    } else {
      console.log('Success', data.MessageId);
    }
  });
};

然后您将按如下方式编写单元测试:

//sqsThingTest.js
var rewire = require("rewire");
var sqsOutputResultSender = rewire('../utility/sqsThing');
const mochaccino = require('mochaccino');
const { expect } = mochaccino;
const sinon = require('sinon');

describe('SQS thing test', function() {
    beforeEach(function () {
        sqsOutputResultSender.__set__("sqs", {
            sendMessage: function() { return 'test' }
        });
    });

  it('sqsOutputResultSender.SQSOutputSender', function() {
    // Where the mock substitution should occur
    const a = sqsOutputResultSender.SQSOutputSender('a');
    expect(a).toEqual('test');
  })
});

此示例 return 是一个 属性 为 sendMessage 的对象,但这可以替换为间谍。

Rewire Docs