我有一个spec文件,期望控制器操作将返回成功。
控制器中的POST api/v1/users/:id/features/block
操作在外部API上调用两个HTTP调用,唯一的区别在于正文。
我已将两个请求和响应放在同一个VCR磁带中,但是当使用磁带时,只有第一个请求被比较,并且当它应该与第二个匹配时失败,导致测试失败。
我正在寻找的方法是让多个请求匹配,以便控制器操作完成并成功返回。
我得到的错误就在最后。
describe "POST /api/v1/users/:id/features/block" do
before(:each) do
@user = FactoryGirl.create(:user)
post :block, user_id: @user.id, block: "0"
end
it "should return 200 OK" do
expect(response).to be_success
end
end
我的VCR配置和RSpec配置的简化版本如下:
VCR.configure do |c|
c.hook_into :webmock
c.default_cassette_options = {
match_requests_on: [:method, :uri, :body_regex]
}
c.register_request_matcher :body_regex do |request_1, request_2|
# Match body against regex if cassette body is "--ruby_regex /regexhere/"
if request_2.body[/^--ruby_regex\s*\//]
regex = request_2.body.gsub(/^--ruby_regex\s*\//, '').gsub(/\/$/, '')
request_1.body[/#{regex}/] ? true : false
else
true # No regex defined, continue processing
end
end
end
RSpec.configure do |c|
c.around(:each) do |example|
options = example.metadata[:vcr] || {}
name = example.metadata[:full_description].split(/\s+/, 2).join("/").underscore.gsub(/[^\w\/]+/, "_")
VCR.use_cassette(name, options, &example)
end
end
end
我在这次比较中使用的盒式磁带的总结版本是:
---
http_interactions:
- request:
method: post
uri: https://upstream/api
body:
string: --ruby_regex /query1.+block/
response:
status:
code: 200
body:
string: { "response": "SUCCESS" }
- request:
method: post
uri: https://upstream/api
body:
string: --ruby_regex /query2.+block/
response:
status:
code: 200
body:
string: { "response": "SUCCESS" }
recorded_at: Fri, 05 Sep 2014 08:26:12 GMT
recorded_with: VCR 2.8.0
测试期间出错:
An HTTP request has been made that VCR does not know how to handle
...
VCR is using the current cassette: (Correct cassette file path)
...
Under the current configuration VCR can not find a suitable HTTP interaction to replay and is prevented from recording new requests.
我不想记录新请求,因为第二个请求会覆盖第一个请求,而不是将第二个请求添加到磁带的末尾。