3

我有一个类,它使用aws-sdk-rails gem(它是aws-sdk-ruby v2的包装器)从 SQS 队列中读取/处理消息。如何模拟 AWS 调用,以便在不访问外部服务的情况下测试我的代码?

通讯器.rb

class Communicator
  def consume_messages
    sqs_client = Aws::SQS::Client.new
    # consume messages until the queue is empty
    loop do
      r = sqs_client.receive_message({
                                              queue_url: "https://sqs.region.amazonaws.com/xxxxxxxxxxxx/foo",
                                              visibility_timeout: 1,
                                              max_number_of_messages: 1
                                     })
      break if (response.message.length == 0)
      # process r.messages.first.body
      r = sqs_client.delete_message({
                                      queue_url: "https://sqs.region.amazonaws.com/xxxxxxxxxxxx/foo",
                                      receipt_handle: r.messages.first.receipt_handle
                                    })
    end
  end
end
4

2 回答 2

9

AWS 开发工具包已提供存根。qv http://docs.aws.amazon.com/sdkforruby/api/Aws/ClientStubs.html了解更多信息(链接到官方文档。)

于 2016-05-31T23:29:12.047 回答
8

我很难找到模拟 AWS 资源的示例。我花了几天时间弄清楚它,并想在 Stack Overflow 上分享我的结果以供后代使用。我使用了 rspec-mocks双打验证双打)。这是communicator.rb问题中示例的示例。

communicator_spec.rb

RSpec.describe Communicator do
  describe "#consume_messages" do
    it "can use rspec doubles & verifying doubles to mock AWS SDK calls" do
      sqs_client = instance_double(Aws::SQS::Client)
      allow(Aws::SQS::Client).to receive(:new).and_return(sqs_client)
      SQSResponse = Struct.new(:messages)
      SQSMessage = Struct.new(:body, :receipt_handle)
      response = SQSResponse.new([SQSMessage.new(File.read('data/expected_body.json'), "receipt_handle")])
      empty_response = SQSResponse.new([])
      allow(sqs_client).to receive(:receive_message).
                            and_return(response, empty_response)
      allow(sqs_client).to receive(:delete_message).and_return(nil)

      Communicator.new.consume_messages
    end
  end
end
于 2015-11-06T00:34:29.213 回答