2

I have an API that I'm trying to write some specs on and mock out the requests using the VCR gem. The issue I'm having is that when the API returns an empty body, Ruby interprets this as a empty string. However when I use VCR to generate a cassette to mock out a API request, it returns nil. I can easily write code around this, to modify the request back to an empty string resp = '' if resp.nil?, or conditionally write code on how to handle it when the time comes resp.nil? || resp.empty? or Active Supports #blank? but I would much rather not have to write code to simply satisfy my specs.

test_spec.rb

require 'net/http'
require 'vcr'
require 'syck'


def vcr_test
  uri_host = 'www.mocky.io'
  uri_port = 80
  route = '/v2/562e9e7f1100001236933b4b'
  http = Net::HTTP.new(uri_host, uri_port)
  resp = http.get(route)
  resp.body
end

VCR.configure do |c|
  c.cassette_library_dir = 'spec/support/vcr'
  c.hook_into :webmock
  c.configure_rspec_metadata!
  c.default_cassette_options = { :record => :once }
  c.allow_http_connections_when_no_cassette = false
  c.ignore_localhost = false
  c.ignore_hosts 'codeclimate.com'
end

context '#vcr_test' do
  it 'should not return nil' do
    VCR.use_cassette('vcr_test') do
      expect(vcr_test).to eq('')
    end
  end
end

vcr_test.yml

---

http_interactions: 
- request: 
    method: get
    uri: http://www.mocky.io/v2/562e9e7f1100001236933b4b
    body: 
      encoding: US-ASCII
      string: ""
    headers: 
      Accept-Encoding: 
      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
      Accept: 
      - "*/*"
      User-Agent: 
      - Ruby
  response: 
    status: 
      code: 200
      message: OK
    headers: 
      Server: 
      - Cowboy
      Connection: 
      - close
      Content-Type: 
      - application/json; charset=utf-8
      Date: 
      - Mon, 26 Oct 2015 21:52:19 GMT
      Via: 
      - 1.1 vegur
    body: 
      encoding: UTF-8
      string: ""
    http_version: 
  recorded_at: Mon, 26 Oct 2015 21:52:19 GMT
recorded_with: VCR 2.9.3

before cassette is recorded

$ rspec test_spec.rb

Finished in 0.3623 seconds (files took 0.44012 seconds to load)
1 example, 0 failures

after cassette is recorded

$ rspec test_spec.rb

Failures:

  1) #vcr_test should not return nil
     Failure/Error: expect(vcr_test).to eq('')

       expected: ""
            got: nil

       (compared using ==)
     # ./test_spec.rb:28:in `block (3 levels) in <top (required)>'
     # ./test_spec.rb:27:in `block (2 levels) in <top (required)>'

Finished in 0.03411 seconds (files took 0.32761 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./test_spec.rb:26 # #vcr_test should not return nil

How do I get VCR to duplicate the actual response for an empty body?

Travis
  • 13,311
  • 4
  • 26
  • 40
  • 1
    Just a wild guess if you are on Ruby version >= 2.0: What if you don't require 'syck'? Because your cassette parses fine here with the default Ruby 2.1.1 *psych* yaml serializer. – zwippie Oct 27 '15 at 00:18
  • You can also try to serialize cassette as JSON, if your bug persists even then, you may exclude YAML parsing issues: http://www.relishapp.com/vcr/vcr/v/2-9-3/docs/cassettes/cassette-format#request/response-data-can-be-saved-as-json – Alexey Shein Oct 27 '15 at 15:18
  • It seems like this might be fixed now, in 2019. Not sure exactly which VCR version might have fixed the issue but I had a spec that was returning `nil` in 3.0.3 that works (returns empty string) in 4.0.0. – Ibrahim Feb 20 '19 at 21:46

0 Answers0