sami_analyst
sami_analyst

Reputation: 1839

How to stub .promise() method of node aws-sdk

Since March 2016, the aws sdk for javascript/nodejs does provide the .promise() method on AWS.Request link.

Now I'm running some unit test on the AWS.DynamoDB.DocumentClient(...).get() method (which returns an AWS.Request object) where I also call the .promise() method afterwards to receive a Promise.

Now when I stub the .get() method, Im already returning a Promise, so I want the .promise() method to do nothing more than returning my existing Promise (via "return this").

my code is like

var docClient = AWS.DynamoDB.DocumentClient(...)
docClient.get(...).promise().then(...)

and my test file

var docClient = AWS.DynamoDB.DocumentClient(...)
var batchGetStub = sinon.stub(docClient, 'get').callsFake(function(){return Promise.resolve({id:1337})});
// now I need to also stub the .promise() method
var promiseStub = sinon.stub(docClient.get, 'promise').callsFake(functions(){return this}); // just return the promise back

This doesn't seem to work and I'm getting back the following error

TypeError: Cannot stub non-existent own property promise

I guess I somehow need to declare a .promise method on my fake function.

I tried this with:

this.protoype.promise = function(this){return this};

inside my fake function, but this throws

TypeError: Cannot set property 'promise' of undefined

Upvotes: 1

Views: 3207

Answers (2)

codeBRAVO
codeBRAVO

Reputation: 51

Tristan is right in the answer above: the get() function call does not return a promise, it returns an object that has a function called "promise" on it, which when called should return a promise object.

You can use sinon for this if you want to, but in simple cases it might be preferable to just stub the object manually, as follows:

const getStub = {
   get: (params) => ({
      promise: async () => ({id:1337}),
    })
  };

You don't need to return Promise.resolve if you use the async key word, it will return the {id: 1337} object as a resolved promise by default.

One other note: you're intermingling terminology around get and batchGet. These are different dynamo document client functions with different return signatures, so be careful. Good luck!

Upvotes: 0

Tristan Hessell
Tristan Hessell

Reputation: 950

The problem here is that you're treating the get function as returning a promise - which is doesn't.

get() returns an object that has a function called promise on it, which when called returns a promise object.

So what you actually need to do is something like:

var docClient = AWS.DynamoDB.DocumentClient(...)
var batchGetStub = sinon.stub(docClient, 'get').callsFake(function(){
  return {
    promise: function () {
      return Promise.resolve({id:1337})
    }
  };
});

Upvotes: 7

Related Questions