aws-sdk-mock icon indicating copy to clipboard operation
aws-sdk-mock copied to clipboard

Enable different responses for consecutive calls to the same method

Open nathanielks opened this issue 7 years ago • 6 comments

Use case: SNS.listSubscriptions doesn't guarantee to list all subscriptions if there are less than 100 items in a region (no public documentation on this, this is from a chat with AWS support). It's expected that if there is a NextToken property in the response, that your application will make a subsequent request to the API with that token to get the next page, and so on and so forth.

At the moment, we're only able to mock the first call to a service method. I'd love the ability to mock what the behavior for consecutive calls to the same method!

Similar to https://github.com/dwyl/aws-sdk-mock/issues/58

When I figure it out, I'll report back with any findings.

nathanielks avatar Jun 06 '17 16:06 nathanielks

Ideally it'd be something like:

AWS.mock('SNS', 'listSubscriptions', [{
  Subscriptions: subscriptions,
  NextToken: 'boogers'
}, {
  Subscriptions: moarSubscriptions,
}])

To cover the ability to pass a function, perhaps a generator would be a good option 🤔

nathanielks avatar Jun 06 '17 16:06 nathanielks

+1

benishak avatar Jun 08 '17 15:06 benishak

@benishak here's how I went about doing it:

test('message sends when subscription is not returned in first page of listSubscriptions response', () => {
  const subscriptions = [{
    SubscriptionArn: 'a',
    Owner: '1234567890',
    Protocol: 'lambda',
    Endpoint: 'b',
    TopicArn: 'c'
  }, {
    SubscriptionArn: 'd',
    Owner: '1234567890',
    Protocol: 'lambda',
    Endpoint: 'e',
    TopicArn: 'topicarn'
  }]
  let counter = 0
  const func = (params, callback) => {
    let retval
    switch (counter) {
      case 1:
        retval = {
          Subscriptions: [subscriptions[1]]
        }
        break
      default:
        retval = {
          NextToken: 'boogers',
          Subscriptions: [subscriptions[0]]
        }
    }
    counter++
    callback(null, retval)
  }
  AWS.mock('SNS', 'listSubscriptions', func)
  const SNS = new AWS_SDK.SNS({apiVersion: '2010-03-31'})

  const result = funcToBeTested(SNS)
  const expected = true
  expect(result).toEqual(expected)
})

nathanielks avatar Jun 09 '17 18:06 nathanielks

I'm also using Jest as the testing framework. I also require the actual SDK:

const AWS = require('aws-sdk-mock')
const AWS_SDK = require('aws-sdk')

(I'm using Lambda and don't want to do any transpiling, so using native node 6.10 features)

nathanielks avatar Jun 09 '17 18:06 nathanielks

Sinon stubs have an onCall property, can you use that?

Calling behavior defining methods like returns or throws multiple times overrides the behavior of the stub. As of Sinon version 1.8, you can use the onCall method to make a stub respond differently on consecutive calls.

http://sinonjs.org/releases/v1.17.7/stubs/

jcollum-cambia avatar Sep 05 '17 15:09 jcollum-cambia

Hi, is there an update on this ticket? We face the same issue and need consecutive calls to return different values. @nathanielks thanks for the post, we shamelessly copied your solution :)

sgurnani99 avatar Jun 28 '23 13:06 sgurnani99