Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I stub_responses for DynamoDB query method? #822

Closed
BilalBudhani opened this issue May 21, 2015 · 3 comments
Closed

How do I stub_responses for DynamoDB query method? #822

BilalBudhani opened this issue May 21, 2015 · 3 comments
Labels
guidance Question that needs advice or information.

Comments

@BilalBudhani
Copy link

Hi there,

I've been trying to stub_responses for below query

count_query = dynamod_db_v2.query(table_name: 'Auth', index_name: 'Auth_UserId_Uid_Index', select: 'COUNT', key_conditions: {'userId' => {attribute_value_list: [@user.id], comparison_operator: 'EQ'}})

I've no clue how to stub it. I tried

db = Aws::DynamoDB::Client.new
db.stub_responses(:query, items: [], count: 1)

this doesn't work. I read #770 which says I've to provide original response from DynamoDB API but, I dunno how does it look like. Can you help with this?

@trevorrowe
Copy link
Member

Its possible but there are few signifcant caveats currently:

  • You must provide the protocol structure for DynamoDB which I'll demonstrate below. Its a bit awkward.
  • Passing the structures expected by DynamoDB's protocol will bypass the initial issue, but it will also fail to return the simplified response values you probably expect.
  • Because the currently implementation is a bug, when it is fixed to work as expected, this work-around will stop working.

With all of those disclaimer out of the way, the following example demonstrates stubbing all of the support types by DynamoDB. Note that the list, :l and map, :m entries may be recursive as they support mixed types and can be nested arbitrarily deep. Essentially every value is wrapped in an object that decorates its type.

ddb = Aws::DynamoDB::Client.new(stub_responses:true)
ddb.stub_responses(:query, items: [
  {

    'string' => { s: 'value' }, 
    'string-set' => { ss: ['a', 'b', 'c'] },

    'number' => { n: '10.0' },
    'number-set' => { ns: ['10', '11', '12'] },

    'binary' => { b: 'data' },
    'binary-set' => { bs: ['data1', 'data2'] },

    'boolean' => { bool: true },
    'null' => { null: true },

    # lists, unlike sets allow mixed types
    'list' => { 
      l: [
        { s: 'value' },
        { n: '10' },
        { b: 'data' },
        { bool: false },
        { null: true },
        { l: [] },
        { m: {} },
      ]
    },

    # maps
    'map' => {
      m: {
        'string' => { s: 'value' },
        'number' => { n: '10' },
        'binary' => { b: 'data' },
        'boolean' => { bool: false },
        'null' => { null: true },
        'list' => { l: [] },
        'map' => { m: {} },
      }
    }
  }
], count: 1)

The response will not look like what you would expect because the simplified attributes plugin does not yet support stubbing. Here is what you could expect back. Notice the number attributes are always populated.

ddb.query(table_name:"table-name")  
=> #<struct Aws::DynamoDB::Types::QueryOutput
 items=
  [{"string"=>#<struct Aws::DynamoDB::Types::AttributeValue s="value", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
    "string-set"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=["a", "b", "c"], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
    "number"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="10.0", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
    "number-set"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=["10", "11", "12"], bs=[], m={}, l=[], null=false, bool=false>,
    "binary"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b="data", ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
    "binary-set"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=["data1", "data2"], m={}, l=[], null=false, bool=false>,
    "boolean"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=true>,
    "null"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=true, bool=false>,
    "list"=>
     #<struct Aws::DynamoDB::Types::AttributeValue
      s="StringAttributeValue",
      n="NumberAttributeValue",
      b=nil,
      ss=[],
      ns=[],
      bs=[],
      m={},
      l=
       [#<struct Aws::DynamoDB::Types::AttributeValue s="value", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        #<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="10", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        #<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b="data", ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        #<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        #<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=true, bool=false>,
        #<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        #<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>],
      null=false,
      bool=false>,
    "map"=>
     #<struct Aws::DynamoDB::Types::AttributeValue
      s="StringAttributeValue",
      n="NumberAttributeValue",
      b=nil,
      ss=[],
      ns=[],
      bs=[],
      m=
       {"string"=>#<struct Aws::DynamoDB::Types::AttributeValue s="value", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        "number"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="10", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        "binary"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b="data", ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        "boolean"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        "null"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=true, bool=false>,
        "list"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>,
        "map"=>#<struct Aws::DynamoDB::Types::AttributeValue s="StringAttributeValue", n="NumberAttributeValue", b=nil, ss=[], ns=[], bs=[], m={}, l=[], null=false, bool=false>},
      l=[],
      null=false,
      bool=false>}],
 count=1,
 scanned_count=0,
 last_evaluated_key={},
 consumed_capacity=nil>

My personal recommendation is use DynamoDB local, where everything works as expected, or wait for this to be fixed in master. Im looking at a fix as part of the 2.1 release.

@BilalBudhani
Copy link
Author

@trevorrowe Thanks for posting a brief explanation on this. I will try this out and update the issue with the conclusion.

I would like to use DynamoDB local but, it just got launched few months back and lot of libraries / gems are still using older version of aws-sdk which doesn't support DynamoDB local. These constrain makes it really hard to migrate.

@trevorrowe
Copy link
Member

I did open a follow up issue here: #823. Feel free to ask any questions you have, but the plan currently is to fix this for version 2.1.

@srchase srchase added the guidance Question that needs advice or information. label Dec 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
guidance Question that needs advice or information.
Projects
None yet
Development

No branches or pull requests

3 participants