Stubbing AWS SDK functions to return exceptions (since SDK v. 2.1)

338 views Asked by At

I am using stubbed responses for AWS SDK calls in my specs and I was always able to stub a function with an exception, and then test if it was appropriately caught, or raised, depending on circumstance. This would be a MWE that was working up until now:

let(:aws_creds) { ::Aws::Credentials.new('a', 'b') }
let(:ec2_dummy_client) { ::Aws::EC2::Client.new(credentials: aws_creds, stub_responses: true) }

...

describe 'delete_vpc' do
  it 'raises on non-existent VPC' do
    ec2_dummy_client.stub_responses(:delete_vpc, Aws::EC2::Errors::InvalidVpcIDNotFound)
    expect{ec2_dummy_client.delete_vpc(vpc_id: "vpc-a08b44c5")}.to raise_exception(Aws::EC2::Errors::InvalidVpcIDNotFound)
  end
end

Since upgrading from AWS SDK 2.0 to 2.1, though, I keep getting this (real world) error:

 Failure/Error: expect{ec2_dummy_client.delete_vpc(vpc_id: "vpc-a08b44c5")}.to raise_exception(Aws::EC2::Errors::InvalidVpcIDNotFound)
   expected Aws::EC2::Errors::InvalidVpcIDNotFound, got #<ArgumentError: wrong number of arguments (0 for 2)> with backtrace:
     # ./spec/lib/backends/ec2_backend_spec.rb:691:in `block (5 levels) in <top (required)>'
     # ./spec/lib/backends/ec2_backend_spec.rb:691:in `block (4 levels) in <top (required)>'

I realize my approach of assigning an exception in place of a return structure may have been a little naïve to start with, although it worked. What is the correct approach, though?

1

There are 1 answers

0
Frigo On BEST ANSWER

Turns out stubbing functions with errors is the right apporach but the AWS interface has changed between SDK v. 2.0 and 2.1.

Some errors (not all) are now class ServiceError, whose constructor requires two mandatory attributes: context and message.

For a simple spec, just initializing them is enough, so that the MWE given in the question can be fixed like this:

let(:aws_creds) { ::Aws::Credentials.new('a', 'b') }
let(:ec2_dummy_client) { ::Aws::EC2::Client.new(credentials: aws_creds, stub_responses: true) }

...

describe 'delete_vpc' do
  it 'raises on non-existent VPC' do
    ec2_dummy_client.stub_responses(:delete_vpc, Aws::EC2::Errors::InvalidVpcIDNotFound.new(Seahorse::Client::RequestContext.new,"VPC does not exist"))
    expect{ec2_dummy_client.delete_vpc(vpc_id: "vpc-a08b44c5")}.to raise_exception(Aws::EC2::Errors::InvalidVpcIDNotFound)
  end
end

Note the .new(...) part in the call to stub_responses().