2

im having some issues stubbing this dependency. I know there ir a aws-sdk-mock modules but mi goal its to stub it with sinon and chai. Here is mi code,

Test code

const chai = require('chai');
const sinon = require('sinon');
const chaiHttp = require('chai-http');
const app= require('./app');
chai.use(chaiHttp);

const queryMock =sinon.stub();

const dynamoMock = {
 DocumentClient:sinon.fake.returns({
    query:queryMock
 })
}


let awsDynamoMock;


describe.only('Integration test for activation',()=>{
    beforeEach(() => {
        awsDynamoMock = sinon.stub(require('aws-sdk'),'DynamoDB');   
        awsDynamoMock.returns(dynamoMock);
      })
    afterEach(() => {
        awsDynamoMock.restore();     
      })

    it('Request /endpoint returns HTTP 200 with {} when user exist and all task are done',(done)=>{
        const params = {
            TableName:'table',
            KeyConditionExpression: `client_id= :i`,
            ExpressionAttributeValues: {
              ':i': '23424234'
            },
            ConsistentRead:true
          };

          const userWithNoPendingsMock = {
            Items: [
              {
                client_id: "23424234",
              },
            ],
            Count: 1,
            ScannedCount: 1,
          }

        queryMock.withArgs(params).returns({
            promise:() =>sinon.fake.resolves(userWithNoPendingsMock)
           })


        chai
        .request(app)
        .post("/endpoint")
        .end( (err, res) => {
            chai.expect(res.status).to.be.eql(200);
            chai.expect(res.body).to.eql({});
             done();
        });

    });

})

Connection to dynamoDB to stub

const AWS  = require('aws-sdk');
AWS.config.update({region:'REGION'});

let docClient = false;
const getDynamoSingleton = async () => {

  if (docClient) return docClient;

  docClient = new AWS.DynamoDB.DocumentClient();

  console.log(docClient)
  return docClient
}


module.exports = getDynamoSingleton 

Using DynamoDB example

const getElementById = async (TableName,key,id)=>{

  const docClient = await getDynamoSingleton();

  //Make query params.
  const params = {
    TableName,
    KeyConditionExpression: `${key} = :i`,
    ExpressionAttributeValues: {
      ':i': id
    },
    ConsistentRead:true
  };



  //Run query as promise.
  return docClient.query(params).promise();

}

Im really stuck on this problem, so any help would be useful. I know the problem has something to do with de documentclient

Thanks for the help

juan dubie
  • 21
  • 2

1 Answers1

0

I realize this is an old question, but you can set up a resolvable object with a little trickery. Some inspiration from this answer.

const sandbox = require('sinon').createSandbox();
const AWS = require('aws-sdk');

describe('...', () => {
    it('...',
 (done) => {
        // Create a dummy resolver, which returns an empty object.
        const dummy = {func: () => {}};
        sandbox.stub(dummy, 'func').resolves({some: 'fake response'});


        // Mock docClient.query. Binding to .prototype should make this apply to any `new AWS.DynamoDB.DocumentClient()` calls.
        sandbox.stub(AWS.DynamoDB.DocumentClient.prototype, 'query').returns({promise: dummy.func});

        // Run your tests here.
    });
});

This is cut down to remove a lot of the extra configuration you are doing (and probably need). We create a dummy object with the function func which returns a sinon promise.

Next, we stub the AWS.DynamoDB.DocumentClient prototype so that new AWS.DynamoDB.DocumentClient() will receive our sinon stub.

Third, we configure our DocumentClient prototype stub to return a plain javascript object with a property called promise. This property points to the first dummy object's promise-returning func method.

Now calls to docClient.query(params).promise() should receive a mocked promise. docClient.query(params) will receive the stub sandbox.stub(AWS.DynamoDB.DocumentClient.prototype, ...). And .promise() will be processed from {promise: dummy.func} to refer to the dummy resolver.

EpicVoyage
  • 604
  • 7
  • 20