読者です 読者をやめる 読者になる 読者になる

xengineer’s diary

結果、メモ的な内容になっています。

awsのstub in rspec

はいねもとです。

こんな環境でSQSのテストをrspecで書いていてこまってたのでメモ。

こまったのは、

queue = sqs.create_queue(queue_name: "testq")
sqs.send_message(queue_url: queue.queue_url, message_body: "testdeath")

こんなコードを書いてるところです。

外部への接続なので、当然、stubしてね、って怒られました。

そしてこんなstubを書きました。

stub_request(
  :post,
  "https://sqs.ap-northeast-1.amazonaws.com/"
).to_return(status: 200, body: ""), headers: {})

それで実行してみました。

TypeError:
no implicit conversion of Array into String

ぬぐぐ・・・。配列を文字列に暗に変換しましたね!と。

そんなつもりはないのですが、どこかで変換したみたいです。

queue = sqs.create_queue(queue_name: "testq")
sqs.send_message(queue_url: queue.queue_url, message_body: "testdeath")

send_messageの引数に、create_queueの返り値を渡しているので、そのあたりをあたってみました。

stub_request(
  :post,
  "https://sqs.ap-northeast-1.amazonaws.com/"
).to_return(status: 200, body: Aws::SQS::Types::CreateQueueResult.new(queue_url: "aaa"), headers: {})

変更したのは、returnで、Aws::SQS::Types::CreateQueueResultを作って渡してみたところ。

なぜかというと、下記を見ると、create_queueの戻りはこれ、って言ってるので。

Class: Aws::SQS::Client — AWS SDK for Ruby V2

でも、実行してみたら、

WebMock::Response::InvalidBody:
  must be one of: [Proc, IO, Pathname, String, Array]. 'Aws::SQS::Types::CreateQueueResult' given
# ./spec/controllers/hogehoge_controller_spec.rb:204:in `block (4 levels) in <top (required)>'

どーん!returnに指定できるものは決まっているじゃないですが・・・

意気消沈の助。

先生にたくさん質問して得られた結果。

Client Response Stubs - AWS Developer Blog - Ruby

f:id:xengineer:20160830153659p:plain

Stubbing All Clients

The default config can be used to enable client stubbing globally. This can be very useful when writing tests to enable stubbing in your test helper once.

# stub everything
Aws.config[:stub_responses] = true

つまり、Aws.config[:stub_responses] = trueを設定すれば、AWSの接続は全部勝手にstubしてやるよ!

って太っ腹設定があるのねーーーー!!

ほっ。これで全部解決。

ということで、設定してみました。

before do
  Aws.config[:stub_responses] = true
end

実行してみました。

ArgumentError:
  invalid endpoint, expected URI::HTTP, URI::HTTPS, or nil, got #<URI::Generic String>

はふ・・・もう少し・・・だといいな・・・

なんだろうねぇ・・・と思って、create_queueからの戻りを見てみると、

"String"

って。きっと内部的には、URI.parse(queue_url)的なことをされているのだと思いますが、

URIの文字列ではないので、URI::Generic Stringって言われちゃうんでしょうね・・・

さて、ここから再度先生に質問。

support response stubbing for all instances of a service client · Issue #187 · aws/aws-sdk-core-ruby · GitHub
Using Stubs for the AWS SDK for Ruby - DZone Cloud
Client Response Stubs - AWS Developer Blog - Ruby

この辺を参考にした結果。

before do
  Aws.config[:sqs] = {
    stub_responses: {
      create_queue: {
        queue_url: "http://test.com"
      }
    }
  }
end

これ!これで無事通りました。

ちゃんと、create_queueのときに、queue.queue_urlに、"http://test.com"が入ってきます。

あー、長かった・・・腰が痛いです。