在功能场景中将VCR与Rspec一起使用

joh*_*400 2 ruby rspec ruby-on-rails rspec2 vcr

我有一个Rails 4应用程序,它使用自定义身份验证gem来根据第三方API对用户进行身份验证。该应用程序要求对网站上的大多数操作进行身份验证(访问者可以做的很少)。

我正在尝试使用VCR记录所有集成测试在身份验证期间提出的api请求,但是我可以在SO和Relish文档上找到的所有示例仅涵盖如何在'describe do'规范中使用Rspec进行此操作,如此处所引用:

https://www.relishapp.com/vcr/vcr/v/1-6-0/docs/test-frameworks/usage-with-rspec

由于没有客户参与该项目,因此我正在使用Rspec和Capybara而不是Cucumber编写集成测试,因此我的测试使用的是“功能/场景”格式,如下所示:

feature 'posts' do
  scenario 'a user can log in' do
    # use vcr for api request
    sign_in_user # refers to a method that handles the api call to log in a user, which is what I would like VCR to record.
    expect(page).to have_content("User signed in successfully")
  end
end
Run Code Online (Sandbox Code Playgroud)

使用文档中描述的命令:

use_vcr_cassette
Run Code Online (Sandbox Code Playgroud)

在“方案”块中,返回错误:

Failure/Error: use_vcr_cassette

undefined local variable or method `use_vcr_cassette' for #<RSpec::ExampleGroups::Posts:0x007fb858369c38>
Run Code Online (Sandbox Code Playgroud)

我按照文档在我的spec / rails_helper.rb(包含在spec / spec_helper.rb中)中设置了VCR ...基本上看起来像这样:

require 'vcr'
VCR.configure do |c|
  c.cassette_library_dir = 'support/vcr_cassettes'
  c.hook_into :webmock
end
Run Code Online (Sandbox Code Playgroud)

显然,在我的Gemfile开发/测试组中添加了gem'vcr',这是在控制台中进行的,并且可以从测试内部进行binding.pry。

有人在Rspec功能中使用过VCR吗?或对解决方法有任何建议?

提前致谢

joh*_*400 5

解决方案:Taryn East让我找到了解决方案,但与尝试进行此操作的人员发布的链接略有不同。

这是spec / rails_helper.rb或spec / spec_helper.rb中最基本的配置:

require 'vcr'
VCR.configure do |c|
    c.cassette_library_dir = 'spec/cassettes'
    c.hook_into :webmock
    c.configure_rspec_metadata!
end
Run Code Online (Sandbox Code Playgroud)

使用c.configure_rspec_metadata!是Rspec处理:vcr标记所必需的。

在Rspec Feature规范中:

feature 'users' do
  scenario 'logged in users should be able to do stuff', :vcr do
    # authenticate user or make other http request here 
  end
end
Run Code Online (Sandbox Code Playgroud)

奇怪的是,在我的测试中-VCR记录响应,如果第一次通过,但是第二次失败。我将此归因于响应的存储方式与收到的信息不同。

在正常要求下(使用激子),如下所示:

resp = Excon.post(url, :body => data, :headers => { "Content-Type" => "application/x-www-form-urlencoded", "Authorization" => authorization_header })
Run Code Online (Sandbox Code Playgroud)

响应具有以下格式的标头:

resp.headers["oauth_token"]
Run Code Online (Sandbox Code Playgroud)

它返回一个oauth令牌。

在VCR响应中,它的存储方式不同,只能通过以下方式访问:

resp.headers["Oauth-Token"]
Run Code Online (Sandbox Code Playgroud)

这很奇怪,但是可行。这可能是VCR的错误或Excon的某些问题...太忙了以至于无法立即解决这个问题,但是如果其他任何人使用此设置并通过实时http请求获得通过测试而失败,则请注意使用VCR盒带进行测试。一个快速的解决方法是更改​​VCR卡带数据以符合您的代码期望,或者修改您的代码以接受任一可用值。