LoginSignup
14
12

More than 3 years have passed since last update.

gem webmock の README を翻訳しました

Last updated at Posted at 2020-04-29

概要

gem webmockREADME を翻訳しました。

  • 翻訳について

    • 翻訳サービス DeeplGoole翻訳 の訳文を参考にしている箇所があります。
    • 翻訳対象のコミットハッシュ
    • 非公式の翻訳です。
    • 訳文がおかしい箇所があったら指摘をもらえると幸いです。
  • ライセンスについて

目次

WebMock

Ruby の HTTP リクエストにおいて期待値のスタブと設定をするライブラリです。

機能

  • 低 HTTP クライアントライブラリレベル(HTTP ライブラリを変更してもテストを変更する必要はありません)におけるHTTP リクエストのスタブ。
  • HTTP リクエスト上の期待値の設定と確認。
  • HTTP メソッド、HTTP URI、HTTP ヘッダ、HTTP ボディをもとにしたリクエストとの一致。
  • 異なる表現における同じ URI の優れた一致(エンコード済みの URI と未エンコードの URI も一致させる)
  • 異なる表現における同じヘッダの優れた一致。
  • Test::Unit のサポート
  • RSpec のサポート
  • MiniTest のサポート

サポートされている HTTP ライブラリ

  • Net::HTTP and libraries based on Net::HTTP (i.e RightHttpConnection, REST Client, HTTParty)
  • HTTPClient
  • Patron
  • EM-HTTP-Request
  • Curb (currently only Curb::Easy)
  • Typhoeus (currently only Typhoeus::Hydra)
  • Excon
  • HTTP Gem
  • Manticore
  • Async::HTTP::Client

サポートされている Ruby インタープリタ

  • MRI 2.2
  • MRI 2.3
  • MRI 2.4
  • MRI 2.5
  • MRI 2.6
  • MRI 2.7
  • JRuby
  • Rubinius

インストール

gem install webmock

github の master ブランチから最新の開発バージョンをインストールする方法

git clone http://github.com/bblimke/webmock.git
cd webmock
rake install

バージョン v1.x から v2.x へのアップグレード

バージョン 1.x からバージョン 2.x の変更点は CHANGELOG.md に記載されています。

Test::Unit

test/test_helper.rb に下記のコードを追加してください。

require 'webmock/test_unit'

RSpec

spec/spec_helper に下記のコードを追加してください。

require 'webmock/rspec'

MiniTest

test/test_helper に下記のコードを追加してください。

require 'webmock/minitest'

Cucumber

下記を記載した features/support/webmock.rb を作成してください。

require 'webmock/cucumber'

テストフレームワーク外

テストフレームワーク外でも WebMock を使用することができます。

require 'webmock'
include WebMock::API

WebMock.enable!

スタブ

URI のみに基づきかつデフォルトレスポンスをともなったスタブリクエスト

stub_request(:any, "www.example.com")

Net::HTTP.get("www.example.com", "/")    # ===> Success

メソッド、URI、ボディ、ヘッダに基づいたスタブリクエスト

stub_request(:post, "www.example.com").
  with(body: "abc", headers: { 'Content-Length' => 3 })

uri = URI.parse("http://www.example.com/")
req = Net::HTTP::Post.new(uri.path)
req['Content-Length'] = 3

res = Net::HTTP.start(uri.host, uri.port) do |http|
  http.request(req, "abc")
end    # ===> Success

正規表現を使用したリクエストボディとヘッダのマッチ

stub_request(:post, "www.example.com").
  with(body: /world$/, headers: {"Content-Type" => /image\/.+/}).
  to_return(body: "abc")

uri = URI.parse('http://www.example.com/')
req = Net::HTTP::Post.new(uri.path)
req['Content-Type'] = 'image/png'

res = Net::HTTP.start(uri.host, uri.port) do |http|
  http.request(req, 'hello world')
end    # ===> Success

ハッシュを使用したリクエストボディのマッチ。リクエストボディは URL エンコード、JSON、XML で記述しリクエスト可能です。

stub_request(:post, "www.example.com").
  with(body: {data: {a: '1', b: 'five'}})

RestClient.post('www.example.com', "data[a]=1&data[b]=five",
  content_type: 'application/x-www-form-urlencoded')    # ===> Success

RestClient.post('www.example.com', '{"data":{"a":"1","b":"five"}}',
  content_type: 'application/json')    # ===> Success

RestClient.post('www.example.com', '<data a="1" b="five" />',
  content_type: 'application/xml')    # ===> Success

部分ハッシュを使用したリクエストのマッチ

stub_request(:post, "www.example.com").
  with(body: hash_including({data: {a: '1', b: 'five'}}))

RestClient.post('www.example.com', "data[a]=1&data[b]=five&x=1",
:content_type => 'application/x-www-form-urlencoded')    # ===> Success

カスタムリクエストヘッダのマッチ

stub_request(:any, "www.example.com").
  with(headers:{ 'Header-Name' => 'Header-Value' })

uri = URI.parse('http://www.example.com/')
req = Net::HTTP::Post.new(uri.path)
req['Header-Name'] = 'Header-Value'

res = Net::HTTP.start(uri.host, uri.port) do |http|
  http.request(req, 'abc')
end    # ===> Success

同じ名前の複数のヘッダのマッチ

stub_request(:get, 'www.example.com').
  with(headers: {'Accept' => ['image/jpeg', 'image/png'] })

req = Net::HTTP::Get.new("/")
req['Accept'] = ['image/png']
req.add_field('Accept', 'image/jpeg')
Net::HTTP.start("www.example.com") {|http| http.request(req) }    # ===> Success

与えられたブロックを使用したリクエストのマッチ

stub_request(:post, "www.example.com").with { |request| request.body == "abc" }
RestClient.post('www.example.com', 'abc')    # ===> Success

BASIC 認証をともなったリクエスト

stub_request(:get, "www.example.com").with(basic_auth: ['user', 'pass'])
# or
# stub_request(:get, "www.example.com").
#   with(headers: {'Authorization' => "Basic #{ Base64.strict_encode64('user:pass').chomp}"})

Net::HTTP.start('www.example.com') do |http|
  req = Net::HTTP::Get.new('/')
  req.basic_auth 'user', 'pass'
  http.request(req)
end    # ===> Success
重要事項。バージョン 2.0.0 から、WebMock は Authorization ヘッダ内で与えられるクレデンシャルと URL のユーザー情報の中で与えられるクレデンシャルをマッチさせません。つまり、stub_request(:get, "user:pass@www.example.com") は Authorization ヘッダで与えられたクレデンシャルをともなったリクエストとマッチしません。

URL 内の BASIC 認証をともなったリクエスト

stub_request(:get, "user:pass@www.example.com")

RestClient.get('user:pass@www.example.com')    # ===> Success

正規表現を使用した URI のマッチ

stub_request(:any, /example/)

Net::HTTP.get('www.example.com', '/')    # ===> Success

RFC 6570 を使用した URI のマッチ。基本的な例

uri_template = Addressable::Template.new "www.example.com/{id}/"
stub_request(:any, uri_template)

Net::HTTP.get('www.example.com', '/webmock/')    # ===> Success

RFC 6570 を使用した URI のマッチ。応用的な例

uri_template =
  Addressable::Template.new "www.example.com/thing/{id}.json{?x,y,z}{&other*}"
stub_request(:any, uri_template)

Net::HTTP.get('www.example.com',
  '/thing/5.json?x=1&y=2&z=3&anyParam=4')    # ===> Success

ハッシュを使用したクエリパラムのマッチ

stub_request(:get, "www.example.com").with(query: {"a" => ["b", "c"]})

RestClient.get("http://www.example.com/?a[]=b&a[]=c")    # ===> Success

ハッシュを使用した部分的なクエリパラムのマッチ

stub_request(:get, "www.example.com").
  with(query: hash_including({"a" => ["b", "c"]}))

RestClient.get("http://www.example.com/?a[]=b&a[]=c&x=1")    # ===> Success

hash_excluding メソッドを使用した部分的なクエリパラムのマッチ

stub_request(:get, "www.example.com").
  with(query: hash_excluding({"a" => "b"}))

RestClient.get("http://www.example.com/?a=b")    # ===> Failure
RestClient.get("http://www.example.com/?a=c")    # ===> Success

カスタムレスポンスをともなったスタブ

stub_request(:any, "www.example.com").
  to_return(body: "abc", status: 200,
    headers: { 'Content-Length' => 3 })

Net::HTTP.get("www.example.com", '/')    # ===> "abc"

IO オブジェクトとして指定されたボディをともなったレスポンス

File.open('/tmp/response_body.txt', 'w') { |f| f.puts 'abc' }

stub_request(:any, "www.example.com").
  to_return(body: File.new('/tmp/response_body.txt'), status: 200)

Net::HTTP.get('www.example.com', '/')    # ===> "abc\n"

カスタムステータスメッセージをともなったレスポンス

stub_request(:any, "www.example.com").
  to_return(status: [500, "Internal Server Error"])

req = Net::HTTP::Get.new("/")
Net::HTTP.start("www.example.com") { |http| http.request(req) }.
  message    # ===> "Internal Server Error"

curl -is コマンドで記録された未加工のレスポンスを再現する

curl -is www.example.com > /tmp/example_curl_-is_output.txt
raw_response_file = File.new("/tmp/example_curl_-is_output.txt")

上記で生成されたファイルを使用する。

stub_request(:get, "www.example.com").to_return(raw_response_file)

string を引数にすることもできる。

stub_request(:get, "www.example.com").to_return(raw_response_file.read)

ブロックから評価される動的なレスポンス

stub_request(:any, 'www.example.net').
  to_return { |request| {body: request.body} }

RestClient.post('www.example.net', 'abc')    # ===> "abc\n"

ラムダから評価される動的なレスポンス

stub_request(:any, 'www.example.net').
  to_return(lambda { |request| {body: request.body} })

RestClient.post('www.example.net', 'abc')    # ===> "abc\n"

curl -is で記録された動的に評価された未加工のレスポンス

`curl -is www.example.com > /tmp/www.example.com.txt`
stub_request(:get, "www.example.com").
  to_return(lambda { |request| File.new("/tmp/#{request.uri.host.to_s}.txt") })

一部分が動的評価されているレスポンス

stub_request(:any, 'www.example.net').
  to_return(body: lambda { |request| request.body })

RestClient.post('www.example.net', 'abc')    # ===> "abc\n"

Rack レスポンス

class MyRackApp
  def self.call(env)
    [200, {}, ["Hello"]]
  end
end

stub_request(:get, "www.example.com").to_rack(MyRackApp)

RestClient.post('www.example.com')    # ===> "Hello"

エラーを発生させる

クラスで宣言された例外

stub_request(:any, 'www.example.net').to_raise(StandardError)

RestClient.post('www.example.net', 'abc')    # ===> StandardError

インスタンスによる例外

stub_request(:any, 'www.example.net').to_raise(StandardError.new("some error"))

文字列による例外

stub_request(:any, 'www.example.net').to_raise("some error")

タイムアウトエラーを発生させる

stub_request(:any, 'www.example.net').to_timeout

RestClient.post('www.example.net', 'abc')    # ===> RestClient::RequestTimeout

リクエストの繰り返しにおける複数のレスポンス

stub_request(:get, "www.example.com").
  to_return({body: "abc"}, {body: "def"})
Net::HTTP.get('www.example.com', '/')    # ===> "abc\n"
Net::HTTP.get('www.example.com', '/')    # ===> "def\n"

# すべてのレスポンスが使用されたあとは最後のレスポンスがずっと返却される。

Net::HTTP.get('www.example.com', '/')    # ===> "def\n"

to_return()to_raise()to_timeout メソッドを連鎖させた複数のレスポンス

stub_request(:get, "www.example.com").
  to_return({body: "abc"}).then.  #then() メソッドはシンタックスシュガーです。
  to_return({body: "def"}).then.
  to_raise(MyException)

Net::HTTP.get('www.example.com', '/')    # ===> "abc\n"
Net::HTTP.get('www.example.com', '/')    # ===> "def\n"
Net::HTTP.get('www.example.com', '/')    # ===> MyException raised

与えられたレスポンスが返却される回数の指定

stub_request(:get, "www.example.com").
  to_return({body: "abc"}).times(2).then.
  to_return({body: "def"})

Net::HTTP.get('www.example.com', '/')    # ===> "abc\n"
Net::HTTP.get('www.example.com', '/')    # ===> "abc\n"
Net::HTTP.get('www.example.com', '/')    # ===> "def\n"

未使用のスタブの解除

stub_get = stub_request(:get, "www.example.com")
remove_request_stub(stub_get)

ネットワークへの本物のリクエストの許可、不許可

WebMock.allow_net_connect!

stub_request(:any, "www.example.com").to_return(body: "abc")

Net::HTTP.get('www.example.com', '/')    # ===> "abc"

Net::HTTP.get('www.something.com', '/')    # ===> /.+Something.+/

WebMock.disable_net_connect!

Net::HTTP.get('www.something.com', '/')    # ===> Failure

ローカルホストへのリクエストは許可しつつ外部へのリクエストは無効にする

WebMock.disable_net_connect!(allow_localhost: true)

Net::HTTP.get('www.something.com', '/')    # ===> Failure

Net::HTTP.get('localhost:9887', '/')    # ===> Allowed. Perhaps to Selenium?

特定のリクエストは許可しつつ外部へのリクエストは無効にする

許可するリクエストはいくつかの方法で指定することができます。

文字列でホスト名を指定する方法。

WebMock.disable_net_connect!(allow: 'www.example.org')

RestClient.get('www.something.com', '/')    # ===> Failure
RestClient.get('www.example.org', '/')      # ===> Allowed
RestClient.get('www.example.org:8080', '/') # ===> Allowed

文字列でホスト名とポートを指定する方法。

WebMock.disable_net_connect!(allow: 'www.example.org:8080')

RestClient.get('www.something.com', '/')    # ===> Failure
RestClient.get('www.example.org', '/')      # ===> Failure
RestClient.get('www.example.org:8080', '/') # ===> Allowed

URI をマッチする正規表現で指定する方法。

WebMock.disable_net_connect!(allow: %r{ample.org/foo})

RestClient.get('www.example.org', '/foo/bar') # ===> Allowed
RestClient.get('sample.org', '/foo')          # ===> Allowed
RestClient.get('sample.org', '/bar')          # ===> Failure

#call メソッドに応答し、URI オブジェクトを受け取りブーリアンを返すオブジェクトを指定する方法。

blacklist = ['google.com', 'facebook.com', 'apple.com']
allowed_sites = lambda{|uri|
  blacklist.none?{|site| uri.host.include?(site) }
}
WebMock.disable_net_connect!(allow: allowed_sites)

RestClient.get('www.example.org', '/')  # ===> Allowed
RestClient.get('www.facebook.com', '/') # ===> Failure
RestClient.get('apple.com', '/')        # ===> Failure

上記のいづれかのオブジェクトが入っている配列。

WebMock.disable_net_connect!(allow: [
  lambda{|uri| uri.host.length % 2 == 0 },
  /ample.org/,
  'bbc.co.uk',
])

RestClient.get('www.example.org', '/') # ===> Allowed
RestClient.get('bbc.co.uk', '/')       # ===> Allowed
RestClient.get('bbc.com', '/')         # ===> Allowed
RestClient.get('www.bbc.com', '/')     # ===> Failure

Net::HTTP.start 上のコネクト

HTTP プロトコルは3つのステップで出来ています。コネクト、リクエスト、レスポンスです(あるいはクローズが4つ目に入ることもあります)。ほとんどの Ruby HTTP クライアントライブラリはリクエストのステップの一部分としてコネクトを扱っていますが、Net::HTTP は違います。Net::HTTPNet::HTTP.start を使用することによってサーバへのリクエストとは別々にコネクションをオープンすることができます。

WebMock API はリクエストのステップの一部分としてコネクトを行うように作られており、リクエストはスタブしますがコネクトはスタブしません。Net::HTTP.start が呼び出されたとき、WebMock はリクエストがスタブされるかどうかを知りません。デフォルトでは、WebMock はリクエストが実行されるまでコネクトを遅らせます。そのため、リクエストがないときは、Net::HTTP.start は何も行いません。
これは、デフォルトでは WebMock は Net::HTTP の動作を中断させることを意味しています。

この問題を解決するために、WebMock は :net_http_connect_on_start オプションを提供しています。このオプションは WebMock.allow_net_connect!WebMock.disable_net_connect! に渡されます。

WebMock.allow_net_connect!(net_http_connect_on_start: true)

これによって WebMock Net::HTTP adapter は常に Net::HTTP.start 上でコネクトをするようになります。

期待値の設定

Test::Unit の期待値の設定

require 'webmock/test_unit'

stub_request(:any, "www.example.com")

uri = URI.parse('http://www.example.com/')
req = Net::HTTP::Post.new(uri.path)
req['Content-Length'] = 3

res = Net::HTTP.start(uri.host, uri.port) do |http|
  http.request(req, 'abc')
end

assert_requested :post, "http://www.example.com",
  headers: {'Content-Length' => 3}, body: "abc",
  times: 1    # ===> Success

assert_not_requested :get, "http://www.something.com"    # ===> Success

assert_requested(:post, "http://www.example.com",
  times: 1) { |req| req.body == "abc" }

スタブではない本当のリクエストの期待

WebMock.allow_net_connect!

Net::HTTP.get('www.example.com', '/')    # ===> Success

assert_requested :get, "http://www.example.com"    # ===> Success

スタブ上の Test::Unit の期待値の設定

stub_get = stub_request(:get, "www.example.com")
stub_post = stub_request(:post, "www.example.com")

Net::HTTP.get('www.example.com', '/')

assert_requested(stub_get)
assert_not_requested(stub_post)

WebMock モジュール上の RSpec の期待値の設定

この形式は fakeweb-matcher を参考にしています。

require 'webmock/rspec'

expect(WebMock).to have_requested(:get, "www.example.com").
  with(body: "abc", headers: {'Content-Length' => 3}).twice

expect(WebMock).not_to have_requested(:get, "www.something.com")

expect(WebMock).to have_requested(:post, "www.example.com").
  with { |req| req.body == "abc" }
# 括弧の代わりに `do ... end` ブロックを使用すると動作しないことに注意してください。
# 理由は https://github.com/bblimke/webmock/issues/174#issuecomment-34908908 をご覧ください。

expect(WebMock).to have_requested(:get, "www.example.com").
  with(query: {"a" => ["b", "c"]})

expect(WebMock).to have_requested(:get, "www.example.com").
  with(query: hash_including({"a" => ["b", "c"]}))

expect(WebMock).to have_requested(:get, "www.example.com").
  with(body: {"a" => ["b", "c"]},
    headers: {'Content-Type' => 'application/json'})

a_request を使用した RSpec の期待値の設定

expect(a_request(:post, "www.example.com").
  with(body: "abc", headers: {'Content-Length' => 3})).
  to have_been_made.once

expect(a_request(:post, "www.something.com")).to have_been_made.times(3)

expect(a_request(:post, "www.something.com")).to have_been_made.at_least_once

expect(a_request(:post, "www.something.com")).
  to have_been_made.at_least_times(3)

expect(a_request(:post, "www.something.com")).to have_been_made.at_most_twice

expect(a_request(:post, "www.something.com")).to have_been_made.at_most_times(3)

expect(a_request(:any, "www.example.com")).not_to have_been_made

expect(a_request(:post, "www.example.com").with { |req| req.body == "abc" }).
  to have_been_made

expect(a_request(:get, "www.example.com").with(query: {"a" => ["b", "c"]})).
  to have_been_made

expect(a_request(:get, "www.example.com").
  with(query: hash_including({"a" => ["b", "c"]}))).to have_been_made

expect(a_request(:post, "www.example.com").
  with(body: {"a" => ["b", "c"]},
    headers: {'Content-Type' => 'application/json'})).to have_been_made

スタブ上の RSpec の期待値の設定

stub = stub_request(:get, "www.example.com")
# ... make requests ...
expect(stub).to have_been_requested

スタブとリクエスト履歴のリセット

すべてのスタブとリクエスト履歴をリセットしたいときは、WebMock.reset! を使用してください。

stub_request(:any, "www.example.com")

Net::HTTP.get('www.example.com', '/')    # ===> Success

WebMock.reset!

Net::HTTP.get('www.example.com', '/')    # ===> Failure

assert_not_requested :get, "www.example.com"    # ===> Success

リクエストカウンタのリセット

実行済みのリクエストカウンタのみをリセットしたいときは、WebMock.reset_executed_requests! を使用してください。

stub  = stub_request(:get, "www.example.com")
stub2 = stub_request(:get, "www.example2.com")

Net::HTTP.get('www.example.com', '/')
Net::HTTP.get('www.example.com', '/')

Net::HTTP.get('www.example2.com', '/')

expect(stub).to have_been_requested.times(2)
expect(stub2).to have_been_requested.times(1)

WebMock.reset_executed_requests!

expect(stub).not_to have_been_requested
expect(stub2).not_to have_been_requested

WebMock または HTTP クライアントアダプタのみの無効化と有効化

# WebMock の無効化(全アダプタ)
WebMock.disable!

# Net::HTTP を除くすべてのライブラリの WebMock の無効化
WebMock.disable!(except: [:net_http])

# WebMock の有効化(全アダプタ)
WebMock.enable!

# Patron を除くすべてのライブラリの WebMock の有効化
WebMock.enable!(except: [:patron])

リクエストのマッチ

下記の基準を満たすとき、実行されたリクエストはスタブリクエストとマッチします。

  • リクエスト URI がスタブリクエストの URI 、正規表現、RFC 6570 URI テンプレートとマッチするとき。
  • かつ、リクエストメソッドがスタブクリエストのものと同じとき、あるいはスタブリクエストのメソッドが :any のとき。
  • かつ、リクエストボディがスタブクリエストのものと同じとき、あるいはスタブリクエストのボディが指定されていないとき。
  • かつ、リクエストヘッダがスタブリクエストヘッダとマッチするとき、あるいはスタブリクエストヘッダがリクエストヘッダのサブセットとマッチするとき、あるいはスタブリクエストヘッダが指定されないとき。
  • かつ、リクエストが与えられたブロックにマッチするとき、あるいはブロックが与えられていないとき。

スタブの優先順位

最後に宣言された、リクエストにマッチするスタブが常に適用されます。

stub_request(:get, "www.example.com").to_return(body: "abc")
stub_request(:get, "www.example.com").to_return(body: "def")

Net::HTTP.get('www.example.com', '/')    # ====> "def"

URI のマッチ

WebMock は同じ URI のすべての異なった表現形式とマッチします。

下記のすべての URI の表現形式は同じ URI として扱われます。

"www.example.com"
"www.example.com/"
"www.example.com:80"
"www.example.com:80/"
"http://www.example.com"
"http://www.example.com/"
"http://www.example.com:80"
"http://www.example.com:80/"

下記のユーザー情報をともなった URI は同じ URI として扱われます。

"a b:pass@www.example.com"
"a b:pass@www.example.com/"
"a b:pass@www.example.com:80"
"a b:pass@www.example.com:80/"
"http://a b:pass@www.example.com"
"http://a b:pass@www.example.com/"
"http://a b:pass@www.example.com:80"
"http://a b:pass@www.example.com:80/"
"a%20b:pass@www.example.com"
"a%20b:pass@www.example.com/"
"a%20b:pass@www.example.com:80"
"a%20b:pass@www.example.com:80/"
"http://a%20b:pass@www.example.com"
"http://a%20b:pass@www.example.com/"
"http://a%20b:pass@www.example.com:80"
"http://a%20b:pass@www.example.com:80/"

下記も同様です。

"www.example.com/my path/?a=my param&b=c"
"www.example.com/my%20path/?a=my%20param&b=c"
"www.example.com:80/my path/?a=my param&b=c"
"www.example.com:80/my%20path/?a=my%20param&b=c"
"http://www.example.com/my path/?a=my param&b=c"
"http://www.example.com/my%20path/?a=my%20param&b=c"
"http://www.example.com:80/my path/?a=my param&b=c"
"http://www.example.com:80/my%20path/?a=my%20param&b=c"

正規表現を使用して URI をマッチさせる場合、WebMock は同じ URL のすべての有効な形式を使用して URI をマッチさせます。

つまり、www.example.com/my path と同等とみなすので、/my path/www.example.com/my%20path とマッチします。

URI Templates のマッチング

マッチングのために Addressable::Template を使用している場合は、WebMock は Addressable に対するマッチングルールを延期し、RFC 6570 に従います。

クエリパラメーターをマッチさせるために任意の WebMock のメソッドを使用している場合は、Addressable はベース URI とマッチするために使用され、WebMock はクエリパラメーターとマッチします。

ヘッダのマッチング

下記の状況において WebMock はスタブされたリクエストヘッダを使用してリクエストヘッダとマッチします。

  1. スタブリクエストはヘッダを指定されていて、リクエストヘッダはスタブされたヘッダと同じ

    スタブされたヘッダ: { 'Header1' => 'Value1', 'Header2' => 'Value2' }, リクエストされたヘッダ: { 'Header1' => 'Value1', 'Header2' => 'Value2' }

  2. スタブリクエストはヘッダを指定されていて、スタブされたリクエストヘッダはリクエストヘッダのサブセット

    スタブされたヘッダ: { 'Header1' => 'Value1' }, リクエストされたヘッダ: { 'Header1' => 'Value1', 'Header2' => 'Value2' }

  3. スタブリクエストがヘッダを持っていない

    スタブされたヘッダ: nil, リクエストされたヘッダ: { 'Header1' => 'Value1', 'Header2' => 'Value2' }

WebMock はヘッダを標準化し、同じヘッダのすべての形式を同じものとして扱います。
つまり、下記のヘッダの組み合わせは同じものとして扱われます。

{ "Header1" => "value1", content_length: 123, X_CuStOm_hEAder: :value }

{ header1: "value1", "Content-Length" => 123, "x-cuSTOM-HeAder" => "value" }

本物のリクエストとレスポンスの記録とそのリプレイ

アプリケーションの本物の HTTP のやり取りを記録し、それをテストの中でリプレイするためには、WebMock とともに gem VCR を使用することができます。

リクエストのコールバック

WebMock はスタブされたあるいは本物のリクエストのコールバックを引き起こすことができる

WebMock.after_request do |request_signature, response|
  puts "Request #{request_signature} was made and #{response} was returned"
end

Patron で作成されたリクエストは除き、本物のリクエストのみコールバックを引き起こす

WebMock.after_request(except: [:patron],
                      real_requests_only: true) do |req_signature, response|
  puts "Request #{req_signature} was made and #{response} was returned"
end

Bugs and Issues

Please submit them here http://github.com/bblimke/webmock/issues

Issue triage Open Source Helpers

You can contribute by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to subscribe to webmock on CodeTriage.

Suggestions

If you have any suggestions on how to improve WebMock please send an email to the mailing list groups.google.com/group/webmock-users

I'm particularly interested in how the DSL could be improved.

Development

In order to work on Webmock you first need to fork and clone the repo.
Please do any work on a dedicated branch and rebase against master
before sending a pull request.

Credits

The initial lines of this project were written during New Bamboo Hack Day
Thanks to my fellow Bambinos for all the great suggestions!

People who submitted patches and new features or suggested improvements. Many thanks to these people:

  • Ben Pickles
  • Mark Evans
  • Ivan Vega
  • Piotr Usewicz
  • Nick Plante
  • Nick Quaranto
  • Diego E. "Flameeyes" Pettenò
  • Niels Meersschaert
  • Mack Earnhardt
  • Arvicco
  • Sergio Gil
  • Jeffrey Jones
  • Tekin Suleyman
  • Tom Ward
  • Nadim Bitar
  • Myron Marston
  • Sam Phillips
  • Jose Angel Cortinas
  • Razic
  • Steve Tooke
  • Nathaniel Bibler
  • Martyn Loughran
  • Muness Alrubaie
  • Charles Li
  • Ryan Bigg
  • Pete Higgins
  • Hans de Graaff
  • Alastair Brunton
  • Sam Stokes
  • Eugene Bolshakov
  • James Conroy-Finn
  • Salvador Fuentes Jr
  • Alex Rothenberg
  • Aidan Feldman
  • Steve Hull
  • Jay Adkisson
  • Zach Dennis
  • Nikita Fedyashev
  • Lin Jen-Shin
  • David Yeu
  • Andreas Garnæs
  • Roman Shterenzon
  • Chris McGrath
  • Stephen Celis
  • Eugene Pimenov
  • Albert Llop
  • Christopher Pickslay
  • Tammer Saleh
  • Nicolas Fouché
  • Joe Van Dyk
  • Mark Abramov
  • Frank Schumacher
  • Dimitrij Denissenko
  • Marnen Laibow-Koser
  • Evgeniy Dolzhenko
  • Nick Recobra
  • Jordan Elver
  • Joe Karayusuf
  • Paul Cortens
  • jugyo
  • aindustries
  • Eric Oestrich
  • erwanlr
  • Ben Bleything
  • Jon Leighton
  • Ryan Schlesinger
  • Julien Boyer
  • Kevin Glowacz
  • Hans Hasselberg
  • Andrew France
  • Jonathan Hyman
  • Rex Feng
  • Pavel Forkert
  • Jordi Massaguer Pla
  • Jake Benilov
  • Tom Beauvais
  • Mokevnin Kirill
  • Alex Grant
  • Lucas Dohmen
  • Bastien Vaucher
  • Joost Baaij
  • Joel Chippindale
  • Murahashi Sanemat Kenichi
  • Tim Kurvers
  • Ilya Vassilevsky
  • gotwalt
  • Leif Bladt
  • Alex Tomlins
  • Mitsutaka Mimura
  • Tomy Kaira
  • Daniel van Hoesel
  • Ian Asaff
  • Ian Lesperance
  • Matthew Horan
  • Dmitry Gutov
  • Florian Dütsch
  • Manuel Meurer
  • Brian D. Burns
  • Riley Strong
  • Tamir Duberstein
  • Stefano Uliari
  • Alex Stupakov
  • Karen Wang
  • Matt Burke
  • Jon Rowe
  • Aleksey V. Zapparov
  • Praveen Arimbrathodiyil
  • Bo Jeanes
  • Matthew Conway
  • Rob Olson
  • Max Lincoln
  • Oleg Gritsenko
  • Hwan-Joon Choi
  • SHIBATA Hiroshi
  • Caleb Thompson
  • Theo Hultberg
  • Pablo Jairala
  • Insoo Buzz Jung
  • Carlos Alonso Pérez
  • trlorenz
  • Alexander Simonov
  • Thorbjørn Hermanse
  • Mark Lorenz
  • tjsousa
  • Tasos Stathopoulos
  • Dan Buettner
  • Sven Riedel
  • Mark Lorenz
  • Dávid Kovács
  • fishermand46
  • Franky Wahl
  • ChaYoung You
  • Simon Russell
  • Steve Mitchell
  • Mattias Putman
  • Zachary Anker
  • Emmanuel Sambo
  • Ramon Tayag
  • Johannes Schlumberger
  • Siôn Le Roux
  • Matt Palmer
  • Zhao Wen
  • Krzysztof Rygielski
  • Magne Land
  • yurivm
  • Mike Knepper
  • Charles Pence
  • Alexey Zapparov
  • Pablo Brasero
  • Cedric Pimenta
  • Michiel Karnebeek
  • Alex Kestner
  • Manfred Stienstra
  • Tim Diggins
  • Gabriel Chaney
  • Chris Griego
  • Taiki Ono
  • Jonathan Schatz
  • Jose Luis Honorato
  • Aaron Kromer
  • Pavel Jurašek
  • Jake Worth
  • Gabe Martin-Dempesy
  • Michael Grosser
  • Aleksei Maridashvili
  • Ville Lautanala
  • Koichi ITO
  • Jordan Harband
  • Tarmo Tänav
  • Joe Marty
  • Chris Thomson
  • Vít Ondruch
  • George Ulmer
  • Christof Koenig
  • Chung-Yi Chi
  • Olexandr Hoshylyk
  • Janko Marohnić
  • Pat Allan
  • Rick Song
  • NARUSE, Yui
  • Piotr Boniecki
  • Olia Kremmyda
  • Michał Matyas
  • Matt Brictson
  • Kenny Ortmann
  • redbar0n
  • Lukas Pokorny
  • Arkadiy Tetelman
  • Kazato Sugimoto
  • Olle Jonsson
  • Pavel Rosický
  • Geremia Taglialatela
  • Koichi Sasada
  • Yusuke Endoh
  • Grey Baker
  • SoonKhen OwYong
  • Pavel Valena
  • Adam Sokolnicki
  • Jeff Felchner
  • Eike Send
  • Claudio Poli
  • Csaba Apagyi
  • Frederick Cheung
  • Fábio D. Batista
  • Andriy Yanko
  • y-yagi
  • Rafael França
  • George Claghorn
  • Alex Junger
  • Orien Madgwick
  • Andrei Sidorov
  • Marco Costa
  • Ryan Davis
  • Brandur
  • Samuel Williams
  • Patrik Ragnarsson
  • Alex Coomans
  • Vesa Laakso

For a full list of contributors you can visit the
contributors page.

Background

Thank you Fakeweb! This library was inspired by FakeWeb.
I imported some solutions from that project to WebMock. I also copied some code i.e Net:HTTP adapter.
Fakeweb architecture unfortunately didn't allow me to extend it easily with the features I needed.
I also preferred some things to work differently i.e request stub precedence.

Copyright

Copyright (c) 2009-2010 Bartosz Blimke. See LICENSE for details.

14
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12