28

SQS キューにプッシュする NPM モジュールを使用するアプリのテスト カバレッジを作成しようとしていaws-sdkますが、正しくモックする方法がわかりません。

これまでの私のテストは次のとおりです。

var request = require('superagent'),
    expect = require('chai').expect,
    assert = require('chai').assert,
    sinon = require('sinon'),
    AWS = require('aws-sdk'),
    app = require("../../../../app");

describe("Activities", function () {

    describe("POST /activities", function () {

        beforeEach(function(done) {
            sinon.stub(AWS.SQS.prototype, 'sendMessage');

            done();
        });

        afterEach(function(done) {
            AWS.SQS.prototype.sendMessage.restore();

            done();
        });

        it("should call SQS successfully", function (done) {
            var body = {
                "custom_activity_node_id" : "1562",
                "campaign_id" : "318"
            };

            reqest
            .post('/v1/user/123/custom_activity')
            .send(body)
            .set('Content-Type', 'application/json')
            .end(function(err, res) {
                expect(res.status).to.equal(200)

                assert(AWS.SQS.sendMessage.calledOnce);
                assert(AWS.SQS.sendMessage.calledWith(body));
            });
        });

    });

});

私が見ているエラーは次のとおりです。

  1) Activities POST /activities "before each" hook:
     TypeError: Attempted to wrap undefined property sendMessage as function

  2) Activities POST /activities "after each" hook:
     TypeError: Cannot call method 'restore' of undefined

JavaScript でのオブジェクトのモック化に関しては、私は少し初心者sinon.stubなので、無知であることをお許しください。

4

8 に答える 8

26

これは、sinonjs を使用して AWS-SDK をスタブする方法です

import AWS from 'aws-sdk'
import sinon from 'sinon'

let sinonSandbox

const beforeEach = (done) => {
   sinonSandbox = sinon.sandbox.create()
   done()
}

const afterEach = done => {
   sinonSandbox.restore()
   done()
} 
lab.test('test name', (done) => {
    sinonSandbox.stub(AWS, 'SQS')
      .returns({
        getQueueUrl: () => {
          return {
            QueueUrl: 'https://www.sample.com'
          }
        }
    })
    done()
})

基本的に、メインの SQS からすべてのメソッドを制御します。これが誰かを助けることを願っています

于 2017-11-20T07:41:49.287 に答える
4

次のように、Sinon を使用して AWS SDK メソッドをスタブ化できます。

  1. AWS SDK インスタンスをラップし、これを外部から設定できるようにします。

    //Within say, SqsService.js
    var Aws = require('aws-sdk');
    
    exports.sqsClient = new Aws.SQS({
        region: <AWS_REGION>,
        apiVersion: <API_VERSION>,
        accessKeyId: <AWS_ACCESS_KEY_ID>,
        secretAccessKey: <AWS_SECRET_KEY>
    });
    
  2. を使用する場合はsqsClient、代わりにラップされたインスタンスを使用してください。

    var SqsService = require('./SqsService');
    
    function (message, callback) {
        //Do stuff..
        //Then send stuff..
        SqsService.sqsClient.sendMessage(message, callback);
    });
    
  3. ラップされた AWS SDK を使用して、上記のテスト ケースを変更します。

    var request = require('superagent'),
        expect = require('chai').expect,
        assert = require('chai').assert,
        sinon = require('sinon'),
        SqsService = require('./SqsService'), //Import wrapper
        app = require("../../../../app");
    
    describe("Activities", function () {
    
        describe("POST /activities", function () {
    
            var sendMessageStub;
    
            beforeEach(function(done) {
                //Stub like so here
                sendMessageStub = sinon.stub(SqsService.sqsClient, 'sendMessage').callsArgWith(1, null, { MessageId: 'Your desired MessageId' });
    
                done();
            });
    
            afterEach(function(done) {
                sendMessageStub.restore();
    
                done();
            });
    
            it("should call SQS successfully", function (done) {
                var body = {
                    "custom_activity_node_id" : "1562",
                    "campaign_id" : "318"
                };
    
                reqest
                    .post('/v1/user/123/custom_activity')
                    .send(body)
                    .set('Content-Type', 'application/json')
                    .end(function(err, res) {
                        expect(res.status).to.equal(200)
    
                        assert(sendMessageStub.calledOnce);
                        assert(sendMessageStub.calledWith(body));
                });
            });
        });
    });
    
于 2015-02-26T07:25:55.613 に答える
2

Sinon で aws sdk をスタブ化できない理由を正確に説明することはできませんが (おそらく、一部の JS 専門家はそれをより適切に説明できます)、proxyquire では非常にうまく機能します。

プロキシ nodejs は、完全に目立たないようにしながら、テスト中に依存関係を簡単にオーバーライドできるようにするために必要です。

于 2015-02-20T13:17:25.467 に答える
0

AWS SDK v3を使用すると、はるかに簡単になります。埋め込まれたスタブ オブジェクトを作成する必要なく、Promise を直接操作することもできます。

  sinon.stub(SQS.prototype, 'sendMessage').resolves({
    SequenceNumber: '0',
  });

  const sqs = new SQS({});
  const result = await sqs.sendMessage({
    MessageBody: '',
    QueueUrl: '',
  });

  expect(SQS.prototype.sendMessage).to.be.calledOnce;
  expect(result.SequenceNumber).to.be('0');
于 2020-12-17T16:48:36.283 に答える