庫,用於在Ruby中對HTTP請求的固執和設定期望。
http low HTTP客戶端LIB級別的HTTP請求(更改HTTP庫時無需更改測試)
設置和驗證HTTP請求的期望
基於方法,URI,標題和身體的匹配請求
在不同表示形式(也編碼和非編碼表格)中對同一URI的智能匹配
在不同表示形式中對同一標頭的明智匹配。
支持測試::單元
支持RSPEC
支持最大的
ASYNC :: HTTP ::客戶端
路緣(目前僅Curb :: Easy)
em-http-request
Excon
httpclient
HTTP GEM(也稱為http.rb)
httpx
Manticore
NET :: HTTP和其他基於NET :: HTTP的庫,例如:
httparty
休息客戶
贊助人
Typhoeus(目前只有Typhoeus :: Hydra)
MRI 2.6
MRI 2.7
MRI 3.0
MRI 3.1
MRI 3.2
MRI 3.3
jruby
寶石安裝網絡貨物
或或者:
#添加到您的gemfilegroup:測試做 寶石“ Webmock”結尾
git克隆http://github.com/bblimke/webmock.gitcd webmock 耙安裝
自版本1.x以來,Webmock 2.x已有所變化。更改在ChangElog.md中列出
使用以下內容創建文件features/support/webmock.rb
:
需要“ Webmock/Cucumber”
將以下代碼添加到test/test_helper
:
需要“ Webmock/Minitest”
將以下代碼添加到spec/spec_helper
:
需要“ Webmock/rspec”
將以下代碼添加到test/test_helper.rb
需要“ Webmock/test_unit”
您還可以在測試框架外使用網絡貨:
需要'webmock'include webmock :: apiwebmock.enable!
stub_request(:任何“ www.example.com”)net :: http.get(“ www.example.com”,“”/“)#===>成功
stub_request(:post,“ www.example.com”)。 使用(正文:“ ABC”,標題:{'content-length'=> 3})uri = uri.parse(“ http://www.example.com/”)req = net :: http :: post。 new(uri.path)req ['content-Lengths'] = 3Res = net :: http.start(uri.host,uri.port)do | http | http.request(req,“ abc”)結束#===>成功
stub_request(:post,“ www.example.com”)。 使用(Body:/world $/,標頭:{“ content-type” => /image/.+/})。 to_return(body:“ abc”)uri = uri.parse('http://www.example.com/')req = net :: http :: 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')結束#===>成功
stub_request(:post,“ www.example.com”)。 使用(body:{data:{a:'1',b:'五'}})restclient.post('www.example.com',“ data [a] = 1&data [b] =五”, content_type:'application/x-www-form-urlencoded')#===> ScuccesRestClient.post('www.example.com','{“ data”:{“ a”:a“:“ 1”,“ b”: “五”}}', content_type:'application /json')#===> stactionrestclient.post('www.example.com','<data a =“ 1” b =“ fix fix” />', content_type:'application/xml')#===>成功
stub_request(:post,“ www.example.com”)。 使用(正文:hash_including({data:{a:'1',b:'五'}}))restclient.post('www.example.com',“ data [a] = 1&data [a]&data [b ] = fix x =五&x = 1“,:content_type =>'application/x-www-form-urlencoded')#===>成功
stub_request(:任何“ www.example.com”)。 使用(標頭:{'header-name'=>'header-value'})uri = uri.parse('http://www.example.com/')req = net :: http :: http :: http :: post.new( uri.path)req ['header-name'] ='header-value'res = net :: http.start(uri.host,uri.port)do | http | http.request(req,'abc')結束#===>成功
stub_request(:get,'www.example.com')。 使用(標頭:{'cack'=> ['image/jpeg','image/png']})req = net :: http :: http :: get.new(“/”)req ['cack' ] = ['' image/png'] req.add_field('Accept','image/jpeg')net :: http.start(“ www.example.com”){| http | http.request(req)}#===>成功
stub_request(:post,“ www.example.com”)。使用{|請求| request.body ==“ abc”} restclient.post('www.example.com','abc')#===>成功
stub_request(:get,“ www.example.com”)。使用(basic_auth:['user','pass'])#or#stub_request(:get,get,“ www.example.com”)。 {'授權'=>“ basic#{base64.strict_encode64('用戶:pass')。chomp}”}):: http.start('www.example.com')do | http | req = net :: http :: get.new('/') req.basic_auth“用戶”,“通行證” http.request(req)結束#===>成功
stub_request(:get, "user:[email protected]")
與授權標頭中提供的憑據不匹配請求。stub_request(:get,“用戶:[email protected]”)restclient.get('用戶:[email protected]')#===>成功
stub_request(:任何,/example/) net :: http.get('www.example.com','/')#===>成功>
stub_request(:any, - >(uri){true})
uri_template = equbsebable :: template.new“ www.example.com/ {id }/"stub_request(: wand ewany,uri_template)net :: http.get('www.example.com','www.example.com' ,'/webmock/')#= ==>成功
uri_template = 地址:: template.new“ www.example.com/thing/ {id} .json {?x,,Z} {&othertub_request(:any,uri_template)net :: http.get('www。 example.com', '/thing/5.json?x=1&y=2&z=3&anyparam=4')#===>成功
stub_request(:get,“ www.example.com”)。使用(查詢:{“ a” => [b“,” c“ c”]})RESTCLIENT.get(“ http://www.example.com /) ?a [] = b&a [] = c“)#===>成功
stub_request(:get,“ www.example.com”)。 使用(查詢:hash_including({“ a” => [“ b”,“ c”]}))RESTCLIENT.get(“ http://www.example.com/?a [a [a [a] 1“ )#===>成功
stub_request(:get,“ www.example.com”)。 使用(查詢:hash_excluding({“ a“ a” =>“ b”}))restClient.get(“ http://www.example.com/?a=b”)#======== =====> failURERESTCLIENT.get(“ httpp ://www.example.com/?a = c“)#===>成功
stub_request(:任何“ www.example.com”)。 to_return(正文:“ ABC”,狀態:200,標題:{'content-Length'=> 3})net :: http.get(“ www.example.com”,'/'/'/')#= ===>>>>>>>>>>>>>>>“ ABC”
為HTTPARTY的parsed_response
設置適當的內容類型。
stub_request(:任何“ www.example.com”)。to_return主體:'{}',標題:{content_type:'application/json'}
file.open('/tmp/response_body.txt','w'){| f | f.puts'abc'} stub_request(:任何“ www.example.com”)。 to_return(body:file.new('/tmp/response_body.txt'),狀態:200)net :: http.get('www.example.com','/''/')#====> “ abcn”
stub_request(:任何“ www.example.com”)。 to_return_json(body:{foo:“ bar”})net :: http.get('www.example.com','/')#===>“ {” {“ foo”:“ bar”}
stub_request(:任何“ www.example.com”)。 to_return(狀態:[500,“內部服務器錯誤”])req = net :: http :: get.new(“/”)net :: http.start(“ www.example.com”){| http | http.request(req)}。 消息#===>“內部服務器錯誤”
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)
或字符串
stub_request(:get,“ www.example.com”)。to_return(raw_response_file.read)
stub_request(:任何,'www.example.net')。 to_return {|請求| {body:request.body}} restclient.post('www.example.net','abc')#===>“ abcn”
stub_request(:任何,'www.example.net')。 to_return(lambda {| request | {body:request.body}})retclient.post('www.example.net','abc')#====>“ abcn”
curl -is
記錄的動態評估的原始響應curl -is www.example.com > /tmp/www.example.com.txt
stub_request(:get,“ www.example.com”)。 to_return(lambda {|請求| file.new(“/tmp/#{request.uri.host.to_s} .txt”)}))})
stub_request(:任何,'www.example.net')。 to_return(body:lambda {| request | request.body})restclient.post('www.example.net','abc')#====>“ abcn”
上課myrackapp def self.call(env)[200,{},[“ hello”]] endendStub_request(:get,“ www.example.com”)。to_rack(myrackapp)retclient.post('www.example.com')#===>“ hello hello”
stub_request(:Any,'www.example.net')。to_raise(standardError)retClient.post('www.example.net','abc')#====> standarderror
stub_request(:任何,'www.example.net')。to_raise(standarderror.new(“一些錯誤”))
stub_request(:任何,'www.example.net')。to_raise(“一些錯誤”)
stub_request(:任何,'www.example.net')。to_timeoutrestclient.post('www.example.net','abc')#====> retsclient :: requestTime :: requestTimeout
stub_request(:get,“ www.example.com”)。 to_return({{body:“ abc”},{body:“ def”})net :: http.get('www.example.com','/')#===>“ abcn” net :: http 。 get('www.example.com',''/')#===>“ defn”#在使用所有響應後,最後一個響應將返回infiniteluitynet :: http.get('www.example.com' ,',''http.get /')#===>“ defn”
to_return()
, to_raise()
或to_timeout
聲明進行多個響應stub_request(:get,“ www.example.com”)。 to_return({正文:“ abc”})。然後。 #then(then()只是句法糖 to_return({{body:“ def”})。然後。 to_raise(myException)net :: http.get('www.example.com','/')#===>“ abcn” net :: http.get('www.example.com','/') #===>“ defn” net :: http.get('www.example.com','/')#===> myException升高了
stub_request(:get,“ www.example.com”)。 to_return({正文:“ abc”})。時代(2)。 to_return({{body:“ def”})net :: http.get('www.example.com','/')#===>“ abcn” net :: http.get('www.example. com) ','/')#===>“ abcn” net :: http.get('www.example.com','/')#===>“ defn”
stub_get = stub_request(:get,“ www.example.com”)remove_request_stub(stub_get)
webmock.allow_net_connect!stub_request(:任何,“ www.example.com”)。to_return(body:“ abc”)net :: http.get('www.example.com','/''/''/' '/')#=====>> “ abc” net :: http.get('www.something.com','/')#===>/。+something.+/webmock.disable_net_net_net_connect ! ! com','/')#===>失敗
webmock.disable_net_connect!(well_localhost:true)net :: http.get('www.something.com','/')#===> failurenet :: http.get('localhost:localhost:9887','' ,''/') #===>允許。也許是硒?
允許的請求可以通過多種方式指定。
用String
指定主機名:
webmock.disable_net_connect!(允許:'www.example.org')restClient.get('www.something.com','/')#====> failURERESTCLIEST.GET('www.example.org' ') #===> washeRestClient.get('www.example.org:8080','/')#===>允許
用String
指定主機名和端口:
webmock.disable_net_connect!(允許:'www.example.org:8080') restclient.get('www.something.com','/''/')#==========> failureREstClient. get('www.example.org',www.example.org',www.example.org',,, '/')#===> failureRestClient.get('www.example.org:8080',' /')#===>允許
與Regexp
匹配URI:
webmock.disable_net_connect!(允許:%r {ample.org/foo})retClient.get('www.example.org','/foo/bar')#====> washerestclient.get('sample.org 'sample.org'sample.org' ,'/foo')#===> welleRestClient.get('sample.org','/bar')#===>失敗
使用響應#call
的對象,接收URI
對象並返回一個布爾值:
denylist = ['google.com','facebook.com','apple.com'] washe_sites = lambda {| uri | denylist.none?{| site | uri.host.include?(site)}} webmock.disable_net_connect!(允許:washe_sites)restclient.get('www.example.org','/''/')#= ===> wellrestclient.get(' www.facebook。 com',''/')#===> failureRestClient.get('Apple.com','/')#===>失敗
帶有以上任何一個Array
:
webmock.disable_net_connect!(允許:[ lambda {| uri | uri.host.length%2 == 0}, /pample.org/, 'bbc.co.uk',])restClient.get('www.example.org','/')#===> welleRestClient.get('bbc.co.uk','/')#== => washeRestClient.get('bbc.com','/')#===> welleRestClient.get('www.bbc.com','/')#===>失敗
HTTP協議有3個步驟:連接,請求和響應(或4個帶有關閉的)。大多數Ruby HTTP客戶端庫將連接視為請求步驟的一部分,除了Net::HTTP
外,它允許使用Net::HTTP.start
使用NET :: HTTP將連接與請求分開打開。
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)
這迫使網絡貨物NET :: HTTP適配器始終在Net::HTTP.start
。在建立連接時,尚無有關請求或URL的信息,因此Webmock無法決定是否固態請求,並且允許所有連接。僅啟用與特定域(例如測試服務器)的連接:
webmock.allow_net_connect!(net_http_connect_on_start:“ www.example.com”)
需要'webmock/test_unit'stub_request(:任何,“ www.example.com”)uri = uri = uri.parse('http://www.example.com/')req = net :: http :: http : : post.new( uri.path)req ['content-Length'] = 3Res = net :: http.start(uri.host,uri.port)do | http | http.request(req,'abc')endassert_requested:post,“ http://www.example.com”, 標題:{'content-Lengths'=> 3},正文:“ ABC”, 時間:1#===> successAssert_not_requested:get,“ http://www.something.com”#===> successAssert_requested(: 時間:1){| req | req.body ==“ ABC”}
webmock.allow_net_connect!net :: http.get('www.example.com','/')#===> successAssert_requested:get,“ http://www.example.com”#====== >成功>
stub_get = stub_request(:get,“ www.example.com”)stub_post = stub_request(: (stub_get)assert_not_requested(stub_post)
WebMock
模塊上的RSPEC中設置期望這種樣式是從假韋伯捕捉器借來的
需要'WebMock/rspec'expect(webmock)。 使用(body:“ abc”,標題:{'content-length'=> 3})。twiceexpect(webmock).not_to hass_requested(:get,'www.something.com”)期望(webmock)。發帖,“ www .example.com”)。 使用{| req | req.body ==“ abc”}#請注意,帶有'do ... end'而不是捲髮括號的塊無法工作!#為什麼?請參閱此評論https://github.com/bblimke/webmock/issues/174#issuecomment-34908908 expect(webmock).to hass_requested(:get,“ get,” www.example.com”)。 使用(查詢:{“ a” => [“ b”,“ c”]})期望(webmock)。 使用(查詢:hash_including({“ a” => [“ b”,“ c”]}))期望(webmock)。 與(正文:{”
a_request
在RSPEC中設置期望期待(a_request(:post,“ www.example.com”)。 使用(正文:“ ABC”,標頭:{'content-Length'=> 3}))。 to_been_made.onceexpect(a_request(:post,“ www.something.com”)。 (:post,“ www.something.com”)。 to_been_made.at_least_times(3)期望(a_request(:a_request(: )期望(a_request(:any,“ www.example.com”))。 。 to_been_madeexpect(a_request(:get,“ www.example.com”)。使用(QUERY:{“ a” => [b“,” c']}))。 to_been_madeexpect(a_request(:get,“ www.example.com”)。 使用(查詢:hash_including({“ a” => [“ b”,“ c”]})))。 使用(正文:{“ a” => [“ b”,“ c”]},標題:{'content-type'=>'application/json'}))。
stub = stub_request(:get,“ www.example.com”)#...提出請求...期望(stub)。
如果要重置所有當前的存根和請求的歷史記錄,請使用WebMock.reset!
stub_request(:任何“ www.example.com”)net :: http.get('www.example.com','/')#===> successwebmock.reset!net!net :: http.get(' wwwww 。
如果您只想重置執行請求的計數器,請使用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(expect(stub) (stub2)。
#disable webmock(所有適配器)webmock.disable!#disable webmock除net :: httpwebmock.disable!(除外:[:ext:[:net_http])#eNable webmock(all adapters)webmock.enable!除了Patronwebmock.enable! (除外:[:Patron])
執行的請求符合固定請求,如果該請求按照標准通過:
當請求時,URI匹配固定請求URI字符串,RegexP模式或RFC 6570 URI模板
和請求方法與固執請求方法或固執請求方法相同:任何
並且請求主體與未指定的固執請求主體或固執請求主體相同
並請求標頭匹配固定請求標頭,或固定請求標頭匹配請求標頭的子集,或未指定固定請求標頭
並沒有提供請求匹配項或塊
始終將使用最後聲明的存根匹配該請求,即:
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”
WebMock將匹配同一URI的所有不同表示。
即URI的所有以下表示都相等:
“ www.example.com”“ www.example.com/”“ www.example.com:80”“ www.example.com:80/”“ http://www.example.com” www.example.com /""http://www.example.com:80"“http://www.example.com:80/”
Webmock的以下URIS也與UserInfo相同
“ A B:[email protected]”“ A B:[email protected]/” A B:[email protected]:80“” A B:[email protected]:80/“ “ http:// a b:[email protected]”“ http:// a b:[email protected]/”“ http:// a b:[email protected]:80”“” : // a b:[email protected]:80/“” a%20b:[email protected]“” a%20b:[email protected]/“” a%20b:pass@a www.example.com:80"“a%20b:[email protected]:80/"ro"http://a%20b:pass@[email protected]"”“http:// a%20b: [email protected]/“” http:// a%20b:[email protected]:80“” http:// a%20b:[email protected]:80 /“
或這些
“ www.example.com/my path/?a =我的param&b = c”“ www.example.com/my%20path/?a=my%20param&b=c”“ www.example.com:80/my path /path/path/path/path/path/path/path ? c“” http://www.example.com/my%20path/?a=my%20param&b=c“” http://www.example. com:80/my path/?a =我的param&b = c” “ http://www.example.com:80/my%20path/?a=my%20Param&b=c”
如果您提供REGEXP匹配URI,WebMock將嘗試與同一URL的每種有效形式匹配。
即/my path/
將匹配www.example.com/my%20path
,因為它等效於www.example.com/my path
如果使用可尋址::模板進行匹配,則WebMock將將匹配規則推遲到可尋址,該規則符合RFC 6570。
如果您使用任何網絡貨物方法來匹配查詢參數,則可尋址可用於匹配uRI和WebMock的基本訪問,將匹配查詢參數。 如果您不這樣做,那麼Webmock將讓可尋址匹配完整的URI。
在以下情況下,WebMock將與固執請求標頭匹配請求標頭:
Stubbed請求已指定標題,並且請求標頭與固定的標題相同
IE固態標頭: { 'Header1' => 'Value1', 'Header2' => 'Value2' }
{ 'Header1' => 'Value1', 'Header2' => 'Value2' }
Stubbed請求已指定標題,並且固定請求標頭是請求標題的子集
IE固態標頭: { 'Header1' => 'Value1' }
,請求: { 'Header1' => 'Value1', 'Header2' => 'Value2' }
Stubbed請求沒有標題
IE固態標頭: 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交互,並在以後在測試中重播它們,您可以將VCR與Webmock一起使用。
webmock.after_request do | request_signature,響應| puts“請求#{request_signature},並返回#{響應}”結束
webmock.after_request(除:[:patron],real_requests_only:true)do | req_signature,響應| puts“請求#{req_signature},並返回#{響應}”結束
請在這裡提交http://github.com/bblimke/webmock/issues
您可以通過分類問題來做出貢獻,這些問題可能包括複製錯誤報告或詢問重要信息,例如版本號或複制說明。如果您想開始分類問題,那麼一種開始的一種簡單方法是在CodetRiage上訂閱Webmock。
如果您對如何改進網絡貨物有任何建議,請向郵件列表組發送電子郵件。
我對如何改善DSL特別感興趣。
為了在Webmock上工作,您首先需要分叉並克隆回購。在發送拉動請求之前,請在專用的分支上進行任何工作,並反對主人。
該項目的最初幾行是在新的Bamboo Hack Day上寫的,這要歸功於我的Bambinos的所有好建議!
提交補丁和新功能或建議改進的人。非常感謝這些人:
本·泡菜
馬克·埃文斯
伊万·維加(Ivan Vega)
piotr使用WISWICZ
尼克·普蘭特
尼克·誇蘭托(Nick Quaranto)
迭戈·E。
Niels Meersschaert
Mack Earnhardt
阿維科
Sergio Gil
杰弗裡·瓊斯
Tekin Suleyman
湯姆·沃德
納迪姆·比塔(Nadim Bitar)
邁倫·馬斯頓
山姆·菲利普斯(Sam Phillips)
Jose Angel Cortinas
razic
史蒂夫·托克(Steve Tooke)
Nathaniel Bibler
馬丁·拉夫蘭(Martyn Loughran)
Muness Alrubaie
查爾斯·李
瑞安·比格(Ryan Bigg)
皮特·希金斯(Pete Higgins)
漢斯·德·格拉夫(Hans de Graaff)
Alastair Brunton
山姆·斯托克斯
尤金·布爾薩科夫(Eugene Bolshakov)
詹姆斯·康羅伊·菲恩(James Conroy-Finn)
Salvador Fuentes Jr
亞歷克斯·羅森伯格(Alex Rothenberg)
艾丹·費爾德曼(Aidan Feldman)
史蒂夫·赫爾
傑伊·阿德基森(Jay Adkisson)
扎克·丹尼斯(Zach Dennis)
Nikita Fedyashev
林·詹·辛(Lin Jen-Shin)
戴維·尤(David Yeu)
AndreasGarnæs
羅馬shterenzon
克里斯·麥格拉思(Chris McGrath)
斯蒂芬·塞利斯(Stephen Celis)
Eugene Pimenov
阿爾伯特·洛普(Albert Llop)
克里斯托弗·皮克斯(Christopher Picklay)
Tammer Saleh
尼古拉斯·富奇(NicolasFouché)
喬·範·戴克(Joe Van Dyk)
馬克·亞伯拉莫夫
弗蘭克·舒馬赫(Frank Schumacher)
Dimitrij Denissenko
Marnen Laibow-Koser
evgeniy dolzhenko
尼克·雷伯拉(Nick Recobra)
喬丹·埃爾弗(Jordan Elver)
Joe Karayusuf
保羅·科爾滕斯(Paul Cortens)
jugyo
副業
埃里克·奧斯特里奇(Eric Oestrich)
Erwanlr
本·布萊特(Ben Bleything)
喬恩·萊頓(Jon Leighton)
瑞安·施萊辛格(Ryan Schlesinger)
朱利安·博耶(Julien Boyer)
凱文·格洛瓦奇(Kevin Glowacz)
漢斯·哈塞爾伯格(Hans Hasselberg)
安德魯法國
喬納森·海曼(Jonathan Hyman)
雷克斯馮
Pavel Forkert
Jordi Massaguer PLA
傑克·貝尼洛夫(Jake Benilov)
湯姆·波瓦斯
Mokevnin Kirill
亞歷克斯·格蘭特(Alex Grant)
盧卡斯·多門
Bastien Vaucher
Joost Baaij
喬爾·奇賓代爾(Joel Chippindale)
Murahashi Sanemat Kenichi
蒂姆·庫弗斯(Tim Kurvers)
Ilya Vassilevsky
蓋特瓦特
Leif Bladt
亞歷克斯·湯姆林斯(Alex Tomlins)
Mitsutaka Mimura
托米·凱拉(Tomy Kaira)
丹尼爾·範·霍瑟爾(Daniel Van Hoesel)
伊恩·阿薩夫(Ian Asaff)
Ian Lesperance
馬修·霍蘭(Matthew Horan)
Dmitry Gutov
弗洛里安·杜茨(FlorianDütsch)
Manuel Meurer
Brian D. Burns
萊利·斯特朗
塔米爾·杜布斯坦(Tamir Duberstein)
Stefano Uliari
亞歷克斯·史特科夫(Alex Stupakov)
卡倫·王(Karen Wang)
馬特·伯克(Matt Burke)
喬恩·羅(Jon Rowe)
Aleksey V. Zapparov
Praveen Arimbrathodiyil
bo牛仔褲
馬修·康威
羅布·奧爾森(Rob Olson)
馬克斯·林肯
Oleg Gritsenko
Hwan-Joon Choi
希巴塔·海洛西(Shibata Hiroshi)
卡萊布·湯普森(Caleb Thompson)
西奧·霍爾伯格(Theo Hultberg)
帕勃羅·賈拉拉(Pablo Jairala)
insoo嗡嗡作響的榮格
卡洛斯·阿隆索·佩雷斯(Carlos AlonsoPérez)
特洛倫茲
亞歷山大·西蒙諾夫(Alexander Simonov)
ThorbjørnHermanse
馬克·洛倫茲
tjsousa
Tasos Stathopoulos
丹·布特納(Dan Buettner)
Sven Riedel
馬克·洛倫茲
DávidKovács
漁夫46
弗蘭基·瓦爾(Franky Wahl)
chayung you
西蒙·羅素(Simon Russell)
史蒂夫·米切爾(Steve Mitchell)
馬蒂亞斯·普特曼(Mattias Putman)
Zachary Anker
伊曼紐爾·桑博(Emmanuel Sambo)
拉蒙·泰格(Ramon Tayag)
約翰內斯·施倫伯格
SiônLeRoux
馬特·帕爾默
Zhao Wen
Krzysztof Rygielski
瑪格土地
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)
PavelJurašek
傑克·沃思
Gabe Martin-Dempesy
邁克爾·格羅瑟(Michael Grosser)
Aleksei Maridashvili
Ville Lautanala
Koichi Ito
喬丹·哈班
塔摩塔納夫
喬·馬蒂(Joe Marty)
克里斯·湯姆森(Chris Thomson)
VítOndruch
喬治·烏爾默
克里斯托夫·科尼格(Christof Koenig)
Chung-yi Chi
Olexandr Hoshylyk
JankoMarohnić
帕特·艾倫
瑞克歌
Naruse,Yui
Piotr Boniecki
Olia Kremmyda
MichałMatyas
馬特·布里克森(Matt Brictson)
肯尼·奧爾特曼(Kenny Ortmann)
redbar0n
盧卡斯·波科尼(Lukas Pokorny)
Arkadiy Tetelman
kazato sugimoto
奧爾·瓊森(Olle Jonsson)
PavelRosický
Geremia taglialatela
Koichi Sasada
Yusuke Endoh
灰色貝克
很快肯·奧揚
帕維爾·瓦萊納(Pavel Valena)
亞當·索科爾尼克(Adam Sokolnicki)
傑夫·費爾奇納(Jeff Felchner)
eike發送
克勞迪奧·波利(Claudio Poli)
csaba apagyi
弗雷德里克·張
FábioD。Batista
Andriy Yanko
Y-YAGI
拉斐爾·弗朗薩(RafaelFrança)
喬治·克拉格霍恩(George Claghorn)
亞歷克斯·詹格(Alex Junger)
Orien Madgwick
安德烈·西多羅夫(Andrei Sidorov)
馬可·科斯塔(Marco Costa)
瑞安·戴維斯(Ryan Davis)
Brandur
塞繆爾·威廉姆斯
帕特里克·拉格納森(Patrik Ragnarsson)
亞歷克斯·庫曼斯(Alex Coomans)
Vesa Laakso
約翰·霍索恩(John Hawthorn)
Guppy0356
Thilo Rusche
安德魯·斯圖茲(Andrew Stuntz)
盧卡斯·烏耶祖(Lucas Uyezu)
布魯諾縫合
瑞安·克爾(Ryan Kerr)
亞當·哈伍德(Adam Harwood)
本·科希(Ben Koshy)
傑西·鮑斯(Jesse Bowes)
Marek Kasztelnik
CE07C3
江江
Oleksiy Kovyrin
馬特·拉拉茲(Matt Larraz)
托尼·施耐德
NiklasHösl
約翰娜·哈特曼(Johanna Hartmann)
亞歷克斯·維德拉克(Alex Vondrak)
威爾·斯托里
愛德華多·埃爾南德斯(Eduardo Hernandez)
Ojab
Giorgio Gambino
蒂米特里
邁克爾·費爾利
雷贊
去Sueyoshi
塞德里克·索赫勞爾(Cedric Sohrauer)
Akira Matsuda
馬克·斯潘格勒
Henrik NYH
Yoann LeCuyer
盧卡斯·阿瑙德(Lucas Arnaud)
馬克·羅洛夫(Marc Rohloff)
Inkstak
Yuki inoue
布蘭登·韋弗
喬什·尼科爾斯(Josh Nichols)
Ricardo Trindade
耳thip
詹姆斯·布朗
kazuhiro nishiyama
ÉtienneBarrié
馬特·布朗
維克多·馬斯洛夫(Victor Maslov)
Gio Lodi
瑞安·布魯克斯(Ryan Brooks)
雅各布·弗勞茨基(Jacob Frautschi)
克里斯蒂安·施密特(Christian Schmidt)
Rodrigo Argumedo
有關貢獻者的完整列表,您可以訪問貢獻者頁面。
謝謝假韋伯!該圖書館的靈感來自假韋伯。我將一些解決方案從該項目導入到Webmock。我還復制了一些代碼IE NET:HTTP適配器。不幸的是,FakeWeb體系結構不允許我使用所需的功能輕鬆擴展它。我也更喜歡有些事情,以不同的方式工作,即請求存根優先級。
版權(C)2009-2010 Bartosz Blimke。有關詳細信息,請參見許可證。