Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何使用rspec模拟AWS SDK(v2)?_Ruby_Rspec_Mocking_Aws Sdk Ruby - Fatal编程技术网

Ruby 如何使用rspec模拟AWS SDK(v2)?

Ruby 如何使用rspec模拟AWS SDK(v2)?,ruby,rspec,mocking,aws-sdk-ruby,Ruby,Rspec,Mocking,Aws Sdk Ruby,我有一个类,它使用从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({

我有一个类,它使用从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
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

我很难找到模仿AWS资源的例子。我花了几天时间弄明白了这一点,并想与后代分享我在堆栈溢出方面的研究结果。我在问题中使用了(&。这里有一个
communicator.rb
示例

通讯器\u规范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
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

AWS SDK已经提供了stubing.q.v.以获取更多信息(链接到官方文档)。

这个老问题解决了相同的问题:。但是,它是关于stubing,而不是mock。您还可以使用:
allow_any_instance_of(AWS::SQS::Client)。来接收(:receive_message)。和返回(response,empty_response)
在尝试覆盖类后,使用
类\u加倍
,并且wayyyy时间太长-这是我能找到的唯一方法,不会给您带来双重泄漏问题,并且所有方面都正常工作。谢谢。