ห้องสมุดสำหรับ stubbing และกำหนดความคาดหวังในคำขอ HTTP ในทับทิม
การร้องขอ HTTP stubbing ที่ระดับ LIB ไคลเอนต์ HTTP ต่ำ (ไม่จำเป็นต้องเปลี่ยนการทดสอบเมื่อคุณเปลี่ยนไลบรารี HTTP)
การตั้งค่าและตรวจสอบความคาดหวังในคำขอ HTTP
การจับคู่คำขอตามวิธีการ URI ส่วนหัวและร่างกาย
การจับคู่อัจฉริยะของ URIs เดียวกันในการเป็นตัวแทนที่แตกต่างกัน (ยังเข้ารหัสและไม่ได้เข้ารหัสแบบฟอร์ม)
การจับคู่สมาร์ทของส่วนหัวเดียวกันในการเป็นตัวแทนที่แตกต่างกัน
สนับสนุนการทดสอบ :: หน่วย
สนับสนุน RSPEC
สนับสนุน minitest
async :: http :: ลูกค้า
CURB (ปัจจุบันควบคุม :: ง่าย)
em-http-request
เอ็กซอน
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
อัญมณีติดตั้ง webmock
หรืออีกวิธีหนึ่ง:
# เพิ่มลงใน GemFileGroup ของคุณ: ทดสอบทำ gem "webmock" สิ้นสุด
git clone http://github.com/bblimke/webmock.gitcd webmock การติดตั้ง Rake
Webmock 2.x มีการเปลี่ยนแปลงค่อนข้างตั้งแต่เวอร์ชัน 1.x การเปลี่ยนแปลงแสดงอยู่ใน changelog.md
สร้าง features/support/webmock.rb
ด้วยเนื้อหาต่อไปนี้:
ต้องการ 'webmock/แตงกวา'
เพิ่มรหัสต่อไปนี้เพื่อ test/test_helper
:
ต้องการ 'webmock/minitest'
เพิ่มรหัสต่อไปนี้เป็น spec/spec_helper
:
ต้องการ 'webmock/rspec'
เพิ่มรหัสต่อไปนี้ใน test/test_helper.rb
ต้องการ 'webmock/test_unit'
นอกจากนี้คุณยังสามารถใช้ webmock นอกกรอบการทดสอบ:
ต้องการ 'webmock'include webmock :: apiwebmock.enable!
stub_request (: ใด ๆ , "www.example.com") net :: http.get ("www.example.com", "/") # ===> ความสำเร็จ
stub_request (: โพสต์, "www.example.com") ด้วย (body: "abc", ส่วนหัว: {'เนื้อหาความยาว' => 3}) uri = uri.parse ("http://www.example.com/") req = net :: http :: post ใหม่ (uri.path) req ['ความยาวเนื้อหา'] = 3res = net :: http.start (uri.host, uri.port) ทำ | http | http.request (req, "abc") สิ้นสุด # ===> ความสำเร็จ
stub_request (: โพสต์, "www.example.com") ด้วย (body:/world $/, ส่วนหัว: {"content-ype" =>/image/.+/}) to_return (ร่างกาย: "abc") uri = uri.parse ('http://www.example.com/') req = net :: http :: post.new (uri.path) req ['content-ype' ] = 'image/png'res = net :: http.start (uri.host, uri.port) ทำ | http | http.request (req, 'hello world') สิ้นสุด # ===> ความสำเร็จ
stub_request (: โพสต์, "www.example.com") ด้วย (body: {data: {a: '1', b: 'five'}}) restclient.post ('www.example.com', "data [a] = 1 & data [b] = five", content_type: 'แอปพลิเคชัน/x-www-form-urlencoded') # ===> SuccessRestClient.post ('www.example.com', '{"data": {"a": "1", "b": "ห้า"}}', content_type: 'application /json') # ===> SuccessRestClient.post ('www.example.com', '<data a = "1" b = "Five" />' content_type: 'แอปพลิเคชัน/xml') # ===> ความสำเร็จ
stub_request (: โพสต์, "www.example.com") ด้วย (body: hash_including ({data: {a: '1', b: 'five'}})) restclient.post ('www.example.com', "ข้อมูล [a] = 1 & data [b] = ห้า & x = 1 ",: content_type => 'แอปพลิเคชัน/x-www-form-urlencoded') # ===> ความสำเร็จ
stub_request (: ใด ๆ , "www.example.com") ด้วย (ส่วนหัว: {'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) ทำ | http | http.request (req, 'abc') สิ้นสุด # ===> ความสำเร็จ
stub_request (: รับ, 'www.example.com') ด้วย (ส่วนหัว: {'ยอมรับ' => ['image/jpeg', 'image/png']}) req = net :: http :: get.new ("/") req ['ยอมรับ'] = [' image/png '] req.add_field (' ยอมรับ ',' image/jpeg ') net :: http.start ("www.example.com") {| http | http.request (req)} # ===> ความสำเร็จ
stub_request (: โพสต์ "www.example.com") ด้วย {| คำขอ | request.body == "abc"} restclient.post ('www.example.com', 'abc') # ===> ความสำเร็จ
stub_request (: รับ, "www.example.com") ด้วย (masic_auth: ['ผู้ใช้', 'pass'])# หรือ# stub_request (: รับ, "www.example.com") {'การอนุญาต' => "พื้นฐาน #{base64.strict_encode64 ('ผู้ใช้: ผ่าน'). chomp}"}) net :: http.start ('www.example.com') ทำ | http | req = net :: http :: get.new ('/') req.basic_auth 'ผู้ใช้', 'pass' http.request (req) สิ้นสุด # ===> ความสำเร็จ
stub_request(:get, "user:[email protected]")
ไม่ตรงกับคำขอกับข้อมูลรับรองที่ให้ไว้ในส่วนหัวของการอนุญาตstub_request (: รับ, "ผู้ใช้: [email protected]") restclient.get ('ผู้ใช้: [email protected]') # ===> ความสำเร็จ
stub_request (: ใด ๆ ,/example/)net::http.get('www.example.com ','/') # ===> ความสำเร็จ
stub_request (: any, -> (uri) {true})
uri_template = addressable :: template.new "www.example.com/ {id}/"stub_request(:any, uri_template) net :: http.get ('www.example.com', '/webmock/') # = ==> ความสำเร็จ
uri_template = ที่อยู่ได้ :: template.new "www.example.com/thing/ {{id}.json {? example.com ', '/thing/5.json?x=1&y=2&z=3&anyparam=4') # ===> ความสำเร็จ
stub_request (: รับ, "www.example.com") ด้วย (คำถาม: {"a" => ["b", "c"]}) retclient.get ("http://www.example.com/ ? a [] = b & a [] = c ") # ===> ความสำเร็จ
stub_request (: รับ, "www.example.com") ด้วย (แบบสอบถาม: hash_including ({"a" => ["b", "c"]})) restclient.get ("http://www.example.com/ 1 ") # ===> ความสำเร็จ
stub_request (: รับ, "www.example.com") ด้วย (แบบสอบถาม: hash_excluding ({"a" => "b"})) restclient.get ("http://www.example.com/?a=b") : //www.example.com/? a = c ") # ===> ความสำเร็จ
stub_request (: ใด ๆ , "www.example.com") to_return (body: "abc", สถานะ: 200, ส่วนหัว: {'ความยาวเนื้อหา' => 3}) net :: http.get ("www.example.com", '/') # ===> " ABC "
ตั้งค่าประเภทเนื้อหาที่เหมาะสมสำหรับ httparty parsed_response
stub_request (: ใด ๆ , "www.example.com"). to_return body: '{}', ส่วนหัว: {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 (: รับ, "www.example.com"). to_return (raw_response_file)
หรือสตริง
stub_request (: รับ, "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 {| คำขอ | {body: request.body}}) restclient.post ('www.example.net', 'abc') # ===> "abcn"
curl -is
curl -is www.example.com > /tmp/www.example.com.txt
stub_request (: รับ, "www.example.com") to_return (lambda {| คำขอ | file.new ("/tmp/#{request.uri.host.to_s} .txt")})
stub_request (: ใด ๆ , 'www.example.net') to_return (ร่างกาย: lambda {| คำขอ | request.body}) restclient.post ('www.example.net', 'abc') # ===> "abcn"
คลาส MyRackApp def self.call (env) [200, {}, ["hello" endendstub_request (: รับ, "www.example.com"). to_rack (myrackapp) restclient.post ('www.example.com') # ===> "สวัสดี"
stub_request (: ใด ๆ , 'www.example.net'). to_raise (StandardError) restclient.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'
stub_request (: รับ, "www.example.com") to_return ({body: "abc"}, {body: "def"}) net :: http.get ('www.example.com', '/') # ===> "abcn" net :: http รับ ('www.example.com', '/') # ===> "defn" #AFTER การตอบกลับทั้งหมดจะใช้การตอบกลับครั้งสุดท้ายจะถูกส่งกลับ infinitelynet :: http.get ('www.example.com', ' /') # ===> "defn"
to_return()
, to_raise()
หรือการประกาศ to_timeout
stub_request (: รับ, "www.example.com") to_return ({body: "abc"}) จากนั้น #จากนั้น () เป็นเพียงน้ำตาลวากยสัมพันธ์ 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 (: รับ, "www.example.com") to_return ({body: "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 (: รับ, "www.example.com") remove_request_stub (stub_get)
webmock.allow_net_connect! stub_request (: ใด ๆ , "www.example.com"). to_return (ร่างกาย: "abc") net :: http.get ('www.example.com', '/') # ===> "abc" net :: http.get ('www.something.com', '/') # ===> /.+something.+/webmock.disable_net_connect! com ','/') # ===> ความล้มเหลว
webmock.disable_net_connect! (ally_localhost: จริง) net :: http.get ('www.something.com', '/') # ===> failuRenet :: http.get ('localhost: 9887', '/') # ===> อนุญาต อาจจะเป็นซีลีเนียม?
สามารถระบุคำขอได้หลายวิธี
ด้วย String
ที่ระบุชื่อโฮสต์:
webmock.disable_net_connect! (อนุญาต: 'www.example.org') restclient.get ('www.something.com', '/') # ===> failulerestclient.get ('www.example.org', '/== ') # ===> leadingRestClient.get (' www.example.org:8080 ','/') # ===> อนุญาต
ด้วย String
ที่ระบุชื่อโฮสต์และพอร์ต:
webmock.disable_net_connect! (อนุญาต: 'www.example.org:8080')restclient.get('www.something.com', '/') # ===> failulerestclient.get (www.example.org ' '/') # ===> failulerestClient.get ('www.example.org:8080', ','/') # ===> อนุญาต
ด้วย Regexp
ที่ตรงกับ URI:
webmock.disable_net_connect! (อนุญาต: %r {apple.org/foo}) RestClient.get ('www.example.org', '/foo/bar') # ===> leadingRestClient.get ('sample.org' , '/foo') # ===> redaleRestClient.get ('sample.org', '/bar') # ===> ความล้มเหลว
ด้วยวัตถุที่ตอบสนองต่อ #call
รับวัตถุ URI
และส่งคืนบูลีน:
denylist = ['google.com', 'facebook.com', 'apple.com'] redale_sites = lambda {| uri | denylist.none? {| ไซต์ | uri.host.include? (ไซต์)}} webmock.disable_net_connect! (อนุญาต: อนุญาตให้: อนุญาตให้ใช้) restclient.get ('www.example.org', '/') # ===> redaleRestClient.get ('www.facebook com ','/') # ===> failulerestClient.get (' Apple.com ','/') # ===> ความล้มเหลว
ด้วย Array
ใด ๆ ข้างต้น:
webmock.disable_net_connect! (อนุญาต: [ Lambda {| uri | uri.host.length % 2 == 0} /AMPLE.org/, 'bbc.co.uk',]) RestClient.get ('www.example.org', '/') # ===> leadingRestClient.get ('bbc.co.uk', '/') # == => redaleRestClient.get ('bbc.com', '/') # ===> redaleRestClient.get ('www.bbc.com', '/') # ===> ความล้มเหลว
โปรโตคอล HTTP มี 3 ขั้นตอน: เชื่อมต่อการร้องขอและการตอบกลับ (หรือ 4 พร้อมปิด) ไลบรารีไคลเอนต์ Ruby HTTP ส่วนใหญ่ปฏิบัติต่อการเชื่อมต่อเป็นส่วนหนึ่งของขั้นตอนการร้องขอยกเว้น Net::HTTP
ซึ่งอนุญาตให้เปิดการเชื่อมต่อกับเซิร์ฟเวอร์แยกต่างหากไปยังคำขอโดยใช้ Net::HTTP.start
Webmock API ได้รับการออกแบบด้วยการเชื่อมต่อเป็นส่วนหนึ่งของขั้นตอนการร้องขอและอนุญาตให้มีการร้องขอ Stubbing เท่านั้นไม่ใช่การเชื่อมต่อ เมื่อ Net::HTTP.start
ถูกเรียกใช้เว็บมอคยังไม่ทราบว่ามีการร้องขอหรือไม่ Webmock โดยค่าเริ่มต้นจะล่าช้าการเชื่อมต่อจนกว่าคำขอจะถูกเรียกใช้ดังนั้นเมื่อไม่มีการร้องขอ Net::HTTP.start
ไม่ได้ทำอะไรเลย ซึ่งหมายความว่า Webmock จะทำลายพฤติกรรมของ NET :: HTTP โดยค่าเริ่มต้น!
ในการแก้ปัญหาปัญหานี้ข้อเสนอเว็บม็อก :net_http_connect_on_start
ซึ่งสามารถส่งผ่านไปยัง WebMock.allow_net_connect!
และ WebMock.disable_net_connect!
วิธีการเช่น
webmock.allow_net_connect! (net_http_connect_on_start: จริง)
นี้บังคับให้ใช้งาน Webmock Net :: HTTP Adapter เพื่อเชื่อมต่อบน Net::HTTP.start
เสมอ ในช่วงเวลาที่มีการเชื่อมต่อไม่มีข้อมูลเกี่ยวกับการร้องขอหรือ URL ดังนั้นเว็บมอคยังไม่สามารถตัดสินใจได้ว่าจะมีการร้องขอหรือไม่และอนุญาตให้เชื่อมต่อทั้งหมดได้ เพื่อเปิดใช้งานการเชื่อมต่อเฉพาะโดเมนเฉพาะ (เช่นเซิร์ฟเวอร์ทดสอบของคุณ) ใช้:
webmock.allow_net_connect! (net_http_connect_on_start: "www.example.com")
ต้องการ 'webmock/test_unit'stub_request (: ใด ๆ , "www.example.com") uri = uri.parse (' http://www.example.com/ ') req = net :: http :: post.new ( uri.path) req ['ความยาวเนื้อหา'] = 3res = net :: http.start (uri.host, uri.port) ทำ | http | http.request (req, 'abc') endassert_requested: โพสต์, "http://www.example.com" ส่วนหัว: {'ความยาวเนื้อหา' => 3}, body: "abc", เวลา: 1 # ===> SuccessAssert_Not_Requested: Get, "http://www.something.com" # ===> SuccessAssert_requested (: โพสต์ "http://www.example.com" ครั้ง: 1) {| req | req.body == "abc"}
webmock.allow_net_connect! net :: http.get ('www.example.com', '/') # ===> SuccessAssert_requested: รับ, "http://www.example.com" # ===> ความสำเร็จ
stub_get = stub_request (: รับ, "www.example.com") stub_post = stub_request (: โพสต์, "www.example.com") net :: http.get ('www.example.com', '/') assert_requested (stub_get) assert_not_requested (stub_post)
WebMock
สไตล์นี้ยืมมาจากตัวจับคู่ FakeWeb
ต้องการ 'webmock/rspec'expect (webmock) .to have_requested (: รับ, "www.example.com") ด้วย (body: "abc", ส่วนหัว: {'เนื้อหาความยาว' => 3}). สองครั้ง (webmock) .not_to have_requested (: รับ, "www.something.com") โพสต์, "www.example.com") ด้วย {| req | req.body == "abc"}# บันทึกว่าบล็อกที่มี `do ... จบ 'แทนที่จะเป็นวงเล็บหยิกจะไม่ทำงาน!# ทำไม? ดูความคิดเห็นนี้ https://github.com/bblimke/webmock/issues/174#issuecomment-34908908Expect(webmock).to Have_requested (: รับ, "www.example.com") ด้วย (แบบสอบถาม: {"A" => ["B", "C"]}) คาดหวัง (เว็บโมค็อก). ถึง HAS_REQUESTED (: รับ, "www.example.com") ด้วย (แบบสอบถาม: hash_including ({"a" => ["b", "c"]})) คาดหวัง (เว็บโมฆะ). ถึง have_requested (: รับ, "www.example.com") ด้วย (body: {"a" => ["b", "c"]}, ส่วนหัว: {'content-type' => 'application/json'})
a_request
คาดหวัง (a_request (: โพสต์, "www.example.com") ด้วย (body: "abc" ส่วนหัว: {'เนื้อหาความยาว' => 3})) to have_been_made.onceexpect (a_request (: โพสต์, "www.something.com")). to have_been_made.times (3) คาดหวัง (a_request (: โพสต์, "www.something.com)) (: โพสต์ "www.something.com")) to have_been_made.at_least_times (3) คาดหวัง (a_request (: โพสต์, "www.something.com")). ถึง have_been_made.at_most_twiceexpect (a_request (: โพสต์, "www.something.com). ) คาดหวัง (a_request (: ใด ๆ , "www.example.com")). not_to have_been_madeexpect (a_request (: โพสต์, "www.example.com") ด้วย {| req | req.body == "abc"})) . ถึง HAS_BEEN_MADEEXPECT (a_request (: รับ, "www.example.com") ด้วย (คำถาม: {"a" => ["b", "c"]})) ถึง HAS_BEEN_MADEEXPECT (a_request (: รับ, "www.example.com") ด้วย (แบบสอบถาม: hash_including ({"a" => ["b", "c"]})). to have_been_madeexpect (a_request (: โพสต์, "www.example.com") ด้วย (body: {"a" => ["b", "c"]}, ส่วนหัว: {'content-type' => 'application/json'})). ถึง have_been_made
stub = stub_request (: รับ, "www.example.com")# ... ทำการร้องขอ ... คาดหวัง (stub). ถึง have_been_requested
หากคุณต้องการรีเซ็ตต้นขั้วปัจจุบันและประวัติของคำขอใช้ WebMock.reset!
stub_request (: ใด ๆ , "www.example.com") net :: http.get ('www.example.com', '/') # ===> successwebmock.reset! net :: http.get ('www .example.com ','/') # ===> failureAsSert_Not_requested: รับ, "www.example.com" # ===> ความสำเร็จ
หากคุณต้องการรีเซ็ต เฉพาะ เคาน์เตอร์ของคำขอที่ดำเนินการใช้ WebMock.reset_executed_requests!
stub = stub_request (: รับ, "www.example.com") stub2 = stub_request (: รับ, "www.example2.com") net :: http.get ('www.example.com', '/') net :: http.get ('www.example.com', '/')net::http.get('www.example2.com', '/') (stub2) .to have_been_requested.times (1) webmock.reset_executed_requests!
# ปิดใช้งาน Webmock (อะแดปเตอร์ทั้งหมด) Webmock.Disable!# ปิดการใช้งาน Webmock สำหรับ libs ทั้งหมดยกเว้น net :: httpwebmock.disable! (ยกเว้น: [: net_http])# เปิดใช้งาน webmock (อะแดปเตอร์ทั้งหมด) webmock.enable! ยกเว้น Patronwebmock.enable! (ยกเว้น: [: ผู้อุปถัมภ์])
คำขอที่ดำเนินการตรงกับคำขอ stubbed หากผ่านเกณฑ์ดังต่อไปนี้:
เมื่อขอ URI ตรงกับ stubbed request uri string รูปแบบ regexp หรือ rfc 6570 template uri
และวิธีการขอเป็นวิธีเดียวกับวิธีการร้องขอ stubbed หรือวิธีการร้องขอ stubbed คือ: ใด ๆ
และไม่ได้ระบุตัวถังขอ
และคำขอส่วนหัวที่ตรงกับส่วนหัวคำขอ stubbed หรือส่วนหัวคำขอ stubbed ตรงกับชุดย่อยของส่วนหัวคำขอหรือไม่ได้ระบุส่วนหัวคำขอ stubbed
และไม่ได้ให้การจับคู่คำขอที่มีให้บล็อกหรือบล็อก
การจับคู่สตับที่ประกาศครั้งสุดท้ายมักจะใช้เช่น:
stub_request (: รับ, "www.example.com"). to_return (body: "abc") stub_request (: get, "www.example.com"). to_return (ร่างกาย: "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" "http: // www.example.com/""phttp://www.example.com:80""http://www.example.com:80/ "
URIs ต่อไปนี้กับ UserInfo ก็เท่ากันสำหรับ Webmock
"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" "http : // a b: [email protected]: 80/"" A%20b: [email protected] "" A%20b: [email protected]/"" A%20b: pass@ www.example.com:80ญ [email protected]/ "" http: // a%20b: [email protected]: 80 "" http: // a%20b: [email protected]: 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"
หากคุณระบุ regexp ให้ตรงกับ URI เว็บมอคจะพยายามจับคู่กับทุกรูปแบบที่ถูกต้องของ URL เดียวกัน
เช่น /my path/
จะตรงกับ www.example.com/my%20path
เพราะมันเทียบเท่ากับ www.example.com/my path
หากคุณใช้ที่อยู่ :: เทมเพลตสำหรับการจับคู่ WebMock จะเลื่อนกฎการจับคู่ไปยังที่อยู่ซึ่งสอดคล้องกับ RFC 6570
หากคุณใช้วิธีการใด ๆ ของ webmock สำหรับการจับคู่พารามิเตอร์การสืบค้นนั้นสามารถใช้งานได้จะถูกใช้เพื่อให้ตรงกับ URI พื้นฐานและเว็บมอคจะตรงกับพารามิเตอร์แบบสอบถาม หากคุณไม่ทำเช่นนั้น Webmock จะให้ที่อยู่ตรงกับ URI เต็มรูปแบบ
Webmock จะจับคู่ส่วนหัวคำขอกับส่วนหัวคำขอ stubbed ในสถานการณ์ต่อไปนี้:
คำขอ stubbed มีส่วนหัวที่ระบุไว้และการร้องขอส่วนหัวเหมือนกับส่วนหัวของ Stubbed
IE stubbed Headers: { 'Header1' => 'Value1', 'Header2' => 'Value2' }
, ร้องขอ: { 'Header1' => 'Value1', 'Header2' => 'Value2' }
คำขอ stubbed มีส่วนหัวที่ระบุไว้และส่วนหัวคำขอ stubbed เป็นส่วนย่อยของส่วนหัวคำขอ
IE stubbed Headers: { 'Header1' => 'Value1' }
, ร้องขอ: { 'Header1' => 'Value1', 'Header2' => 'Value2' }
คำขอ stubbed ไม่มีส่วนหัว
IE stubbed Headers: nil
, ร้องขอ: { 'Header1' => 'Value1', 'Header2' => 'Value2' }
Webmock Normalises Headers และปฏิบัติต่อส่วนหัวทุกรูปแบบเท่ากัน: IE ส่วนหัวสองชุดต่อไปนี้มีค่าเท่ากัน:
{ "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, Response | วาง "คำขอ #{request_signature} และส่งคืน #{response} กลับมาแล้ว" สิ้นสุด "
webmock.after_request (ยกเว้น: [: ผู้อุปถัมภ์], real_requests_only: จริง) ทำ | req_signature, การตอบสนอง | วาง "คำขอ #{req_signature} ถูกสร้างขึ้นและ #{response} ถูกส่งคืน" สิ้นสุด
โปรดส่งพวกเขาที่นี่ http://github.com/bblimke/webmock/issues
คุณสามารถมีส่วนร่วมโดยปัญหาสามประการซึ่งอาจรวมถึงการทำซ้ำรายงานข้อผิดพลาดหรือขอข้อมูลสำคัญเช่นหมายเลขเวอร์ชันหรือคำแนะนำการทำซ้ำ หากคุณต้องการเริ่มต้นปัญหาการสามวิธีวิธีง่ายๆในการเริ่มต้นคือการสมัครสมาชิกเว็บม็อกบน codetriage
หากคุณมีข้อเสนอแนะเกี่ยวกับวิธีการปรับปรุง webmock โปรดส่งอีเมลไปยังกลุ่มรายชื่อผู้รับจดหมาย google.com/group/webmock-users
ฉันสนใจเป็นพิเศษว่าจะปรับปรุง DSL ได้อย่างไร
ในการทำงานบนเว็บมอคคุณต้องแยกและโคลน repo ก่อน โปรดทำงานใด ๆ ในสาขาเฉพาะและ rebase กับอาจารย์ก่อนส่งคำขอดึง
บรรทัดเริ่มต้นของโครงการนี้ถูกเขียนขึ้นในช่วงวันแฮ็คไม้ไผ่ใหม่ขอบคุณเพื่อนของฉัน Bambinos สำหรับคำแนะนำที่ยอดเยี่ยมทั้งหมด!
ผู้ที่ส่งแพทช์และคุณสมบัติใหม่หรือการปรับปรุงที่แนะนำ ขอบคุณมากสำหรับคนเหล่านี้:
เบ็นดอง
ทำเครื่องหมายอีแวนส์
อีวานเวก้า
Piotr Usewicz
Nick Plante
Nick Quaranto
Diego E. "Flameeyes" Pettenò
Niels Meersschaert
Mack Earnhardt
arvicco
Sergio Gil
เจฟฟรีย์โจนส์
Tekin Suleyman
ทอมวอร์ด
Nadim Bitar
Myron Marston
แซมฟิลลิปส์
Jose Angel Cortinas
น่ากลัว
Steve Tooke
นาธาเนียล Bibler
Martyn Loughran
Muness Alrubaie
Charles Li
Ryan Bigg
Pete Higgins
ฮันส์เดอเกรฟฟ์
Alastair Brunton
Sam Stokes
Eugene Bolshakov
James Conroy-Finn
Salvador Fuentes Jr
Alex Rothenberg
Aidan Feldman
สตีฟฮัลล์
Jay Adkisson
Zach Dennis
Nikita Fedyashev
Lin Jen-shin
David Yeu
Andreas Garnæs
โรมัน Shterenzon
Chris McGrath
สตีเฟ่นเซลิส
Eugene Pimenov
Albert Llop
Christopher Pickslay
Tammer Saleh
Nicolas Fouché
Joe Van Dyk
มาร์ค Abramov
Frank Schumacher
dimitrij denissenko
Marnen Laibow-Koser
Evgeniy Dolzhenko
Nick Recobra
Jordan Elver
Joe Karayusuf
Paul Cortens
jugyo
มีแนวโน้ม
Eric Oestrich
Erwanlr
Ben Bleything
จอน Leighton
Ryan Schlesinger
Julien Boyer
Kevin Glowacz
Hans Hasselberg
แอนดรูว์ฝรั่งเศส
Jonathan Hyman
เร็กซ์เฟิง
Pavel Forkert
Jordi Massaguer Pla
Jake Benilov
Tom Beauvais
Mokevnin Kirill
อเล็กซ์แกรนท์
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
ไรลีย์แข็งแกร่ง
Tamir Duberstein
Stefano uliari
Alex Stupakov
กะเหรี่ยงวัง
แมตต์เบิร์ค
จอนโรว์
Aleksey V. Zapparov
Praveen Arimbrathodiyil
Bo Jeanes
Matthew Conway
Rob Olson
Max Lincoln
Oleg Gritsenko
Hwan-Joon Choi
ชิบาตะฮิโรชิ
Caleb Thompson
Theo Hultberg
Pablo Jairala
Insoo Buzz Jung
Carlos Alonso Pérez
Trlorenz
Alexander Simonov
Thorbjørn Hermanse
มาร์คลอเรนซ์
tjsousa
Tasos Stathopoulos
Dan Buettner
Sven Riedel
มาร์คลอเรนซ์
DávidKovács
ชาวประมง 46
Franky Wahl
chayoung คุณ
Simon Russell
สตีฟมิทเชล
Mattias Putman
Zachary Anker
Emmanuel Sambo
Ramon Tayag
Johannes Schlumberger
Siôn Le Roux
แมตต์พาลเมอร์
Zhao Wen
Krzysztof Rygielski
Magne Land
เป็นมงคล
Mike Knepper
Charles Pence
Alexey Zapparov
Pablo Brasero
เซดริก
Michiel Karnebeek
Alex Kestner
Manfred Stienstra
Tim Diggins
กาเบรียลชานีย์
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
โจมาร์ตี้
คริสทอมสัน
vít ondruch
จอร์จอูลเมอร์
Christof Koenig
Chung-yi Chi
Olexandr Hoshylyk
Janko Marohnić
แพ็ตอัลลัน
เพลงริก
Naruse, Yui
Piotr Boniecki
Olia Kremmyda
Michał Matyas
แมตต์บริคสัน
Kenny Ortmann
redbar0n
Lukas Pokorny
Arkadiy Tetelman
Kazato Sugimoto
Olle Jonsson
Pavel Rosický
Geremia Taglialatela
Koichi Sasada
Yusuke Endoh
เบเกอร์สีเทา
เร็ว ๆ นี้
Pavel Valena
Adam Sokolnicki
Jeff Felchner
eike ส่ง
claudio poli
Csaba apagyi
Frederick Cheung
Fábio D. Batista
Andriy Yanko
Y-Yagi
ราฟาเอลฟรานซ่า
George Claghorn
Alex Junger
Orien Madgwick
Andrei Sidorov
Marco Costa
ไรอันเดวิส
แบรนด์
ซามูเอลวิลเลียมส์
Patrik Ragnarsson
Alex Coomans
Vesa Laakso
John Hawthorn
guppy0356
Thilo Rusche
Andrew Stuntz
Lucas Uyezu
Bruno Sutic
Ryan Kerr
อดัมฮาร์วู้ด
Ben Koshy
Jesse Bowes
Marek Kasztelnik
CE07C3
จุนเจียง
Oleksiy Kovyrin
Matt Larraz
โทนี่ชไนเดอร์
Niklas Hösl
Johanna Hartmann
Alex Vondrak
จะชั้น
Eduardo Hernandez
Ojab
Giorgio Gambino
ทิมมิทรี
Michael Fairley
เรย์ Zane
ไป Sueyoshi
เซดริก
Akira Matsuda
มาร์ค Spangler
Henrik Nyh
Yoann Lecuyer
Lucas Arnaud
Marc Rohloff
หมึก
Yuki Inoue
Brandon Weaver
Josh Nichols
Ricardo Trindade
ที่อยู่ในปฐมวัย
เจมส์บราวน์
Kazuhiro Nishiyama
étienneBarrié
แมตต์บราวน์
Victor Maslov
Gio Lodi
Ryan Brooks
ยาโคบ Frautschi
Christian Schmidt
Rodrigo Argumedo
สำหรับรายชื่อผู้มีส่วนร่วมทั้งหมดคุณสามารถเยี่ยมชมหน้าผู้มีส่วนร่วม
ขอบคุณ FakeWeb! ห้องสมุดนี้ได้รับแรงบันดาลใจจาก FakeWeb ฉันนำเข้าโซลูชันบางอย่างจากโครงการนั้นไปยังเว็บมอค ฉันยังคัดลอกรหัสบางอย่างเช่น NET: อะแดปเตอร์ HTTP สถาปัตยกรรม FakeWeb โชคไม่ดีที่ไม่อนุญาตให้ฉันขยายได้อย่างง่ายดายด้วยคุณสมบัติที่ฉันต้องการ ฉันยังชอบบางสิ่งที่จะทำงานแตกต่างกันเช่นขอความสำคัญของต้นขั้ว
ลิขสิทธิ์ (C) 2009-2010 Bartosz BLIMKE ดูใบอนุญาตสำหรับรายละเอียด