Skip to content

Instantly share code, notes, and snippets.

@dkubb
Created December 5, 2011 18:26
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dkubb/1434673 to your computer and use it in GitHub Desktop.
Save dkubb/1434673 to your computer and use it in GitHub Desktop.
Test Feedzirra w/VCR using an HTTP proxy
#!/usr/bin/env ruby -Ku
# encoding: utf-8
# = Usage
#
# $ rspec test.rb
require 'io/wait'
require 'webrick'
require 'webrick/httpproxy'
require 'rubygems'
require 'active_support/deprecation' # for feedzirra
require 'feedzirra'
require 'rspec'
require 'vcr'
module WEBrick
class VCRProxyServer < HTTPProxyServer
def service(*args)
VCR.use_cassette('proxied') { super(*args) }
end
end
end
VCR.config do |config|
config.stub_with :fakeweb
config.cassette_library_dir = 'cassettes'
config.default_cassette_options = { :record => :new_episodes }
end
describe 'A test with vcr and a transparent proxy' do
IP = '127.0.0.1'
PORT = 9000
before :all do
reader, writer = IO.pipe
@pid = fork do
reader.close
$stderr = writer
server = WEBrick::VCRProxyServer.new(:BindAddress => IP, :Port => PORT)
trap('INT') { server.shutdown }
server.start
end
raise 'VCR Proxy did not start in 10 seconds' unless reader.wait(10)
end
after :all do
Process.kill('INT', @pid)
end
it 'proxies to an RSS feed' do
feed = Feedzirra::Feed.fetch_and_parse(
'http://blog.wildfireapp.com/?feed=rss2',
:proxy_url => IP,
:proxy_port => PORT
)
feed.should be_instance_of(Feedzirra::Parser::RSS)
end
end
@dkubb
Copy link
Author

dkubb commented Dec 5, 2011

This approach is needed because Feedzirra is based on Curb::Multi, which is not currently supported by Feedzirra.

I looked at two other approaches, replacing Feedzirra in the application I maintain (but did not write), or changing it to use a different HTTP library. In both cases the amount of effort it would take seemed to be much greater than the benefits, so I settled on using a proxy until that code is rewritten at some point in the future.

@myronmarston
Copy link

This is pretty cool. I've setup VCR in a local proxy server before so that I can test HTTP requests from other languages (e.g. JS tests in Jasmine) and it worked quite nicely.

FWIW, VCR includes a rack middleware to make this pretty easy. That said, the Webrick approach you've done here looks even simpler. I don't know Webrick really at all (besides using it to boot rack apps) so I wasn't aware it had a built-in-proxy server. I've also been thinking of making a vcr-proxy-server gem that would make this even easier, and seeing your Webrick approach makes me think I may use Webrick instead of Rack like I was planning :).

One other thought: do you have other tests that use this VCR proxy setup besides the one here? Given the fact that you're only asserting that it is an instance of Feedzirra::Parser::RSS, and not actually making any assertion about what gets parsed out of the feed...it seems a bit like overkill to use VCR. Something simpler may do the trick.

@dkubb
Copy link
Author

dkubb commented Dec 5, 2011

@myronmarston: Oh, this was a code spike. The real tests this was written for include over a hundred tests that currently stub out Feedzirra. I was hoping to replace all that code with "real" calls to the backend services and use vcr to record/playback the requests.

I also did use the VCR rack middleware originally. In the git commit history I have a mostly fully functional HTTP proxy built on top of Net::HTTP and the middleware, but once I found out that WEBrick included it's own Net::HTTP based proxy I figured this was a nice way to cut out 50-60 loc. WEBRick's also included support for edge cases, as well as CONNECT support. Oddly enough though it does not include support for proxying PUT/DELETE, although those would be pretty easy to add if needed.

@phoet
Copy link

phoet commented Jan 9, 2012

thx, very helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment