在一次测试中使用多个带 V​​CR 的磁带

joe*_*oey 11 ruby-on-rails vcr

我正在使用 VCR 记录与外部 API 的 http 交互。这是我的(工作)代码:

it 'does xyz....' do
    hook_payload = {ruby_hash: 'here'}

    VCR.use_cassette('my_folder/create_project') do
      VCR.use_cassette('my_folder/get_project') do
        update = Update.new(hook_payload)
        expect { update.call }.to change { Projects.count }.by(1)
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

上面的代码有效,但组织不好,因为我更喜欢expect{}在块外调用。所以,我试过这个,但下面的代码不起作用:

context 'my context', vcr: { group: 'my_folder', cassettes: %w[create_project get_project] } do
    it 'does xyz....' do
        hook_payload = {ruby_hash: 'here'}

        update = Update.new(hook_payload)
        expect { update.call }.to change { Projects.count }.by(1)
      end
Run Code Online (Sandbox Code Playgroud)

但是,此代码不起作用,并且出现以下错误:

VCR is currently using the following cassette: - /Users/me/this_project/spec/fixtures/vcr/my_folder/create_project.yml.

Under the current configuration VCR can not find a suitable HTTP interaction to replay and is prevented from recording new requests.

我 100% 确定这my_folder/get_project.yml是有效的,并且它在项目的其他测试中有效。

我什至%w[create_project get_project]按照它们在我的代码中使用的顺序来放置盒式磁带 ( )。我在这里做错了什么?

Rim*_*ian 4

建议使用该块,但如果您不想这样做,也有其他选择。有两种方法:使用 around 钩子或 before 和 after 钩子。

如果您手动加载磁带,并且在测试之间重复使用磁带,则需要弹出它们,因为它们不喜欢被加载两次(VCR 类比在这里很适用!)。

https://www.rubydoc.info/github/vcr/vcr/VCR:insert_cassette

尝试使用VCR.insert_cassette不需要块的。你需要打电话eject_cassette来表达你的泪水。我尝试了一下并且成功了。顺序并不重要。

it 'does xyz....' do
  hook_payload = {ruby_hash: 'here'}

  VCR.insert_cassette('my_folder/create_project')
  VCR.insert_cassette('my_folder/get_project')
    
  update = Update.new(hook_payload)
    
  expect { update.call }.to change { Projects.count }.by(1)
end

Run Code Online (Sandbox Code Playgroud)

调用弹出以避免加载磁带两次:


VCR.eject_cassette(name: 'my_folder/create_project')
VCR.eject_cassette(name: 'my_folder/get_project')

Run Code Online (Sandbox Code Playgroud)

around 钩子可能也适合你:

around do |example|
  cassettes = [
    { name: 'my_folder/create_project' },
    { name: 'my_folder/get_project' }
  ]
  VCR.use_cassettes cassettes do
    example.run
  end
end
Run Code Online (Sandbox Code Playgroud)

您甚至可以将其与盒式磁带配置结合起来:

it 'whateva', vcr: { cassette_name: 'load another' } do

end
Run Code Online (Sandbox Code Playgroud)