Yesterday I received a great question regarding one of my posts on using around hooks in Rspec.


I’m interested as to what use you would personally use this for.
Can you recommend any use in particular you like?


Below I demonstrate two use cases for around hooks:

1. VCR

VCR automatically stores HTTP responses to prevent your tests from hitting the network each time.

I love VCR but despise the effort required to name each cassette. I took an idea from Ryan Bates and decided to use around hooks to have these cassettes automatically named.

Typical VCR Setup:

1
2
3
4
5
6
7
8
it "shows Beverly Hills given 90210" do
  VCR.use_cassette "zip_code/90210" do
    visit root_path
    fill_in "zip_code", with: "90210"
    click_on "Lookup"
    page.should have_content "Beverly Hills"
  end
end

The typical VCR setup requires that you name the file where the HTTP response will live. I’m too lazy to accept this.

My VCR Setup:

1
2
3
4
5
6
it "shows Beverly Hills given 90210", :vcr do
  visit root_path
  fill_in "zip_code", with: "90210"
  click_on "Lookup"
  page.should have_content "Beverly Hills"
end

I simply pass :vcr after the description for automatic file naming. This is accomplished by using around hooks in my spec_helper.rb file. Check out the code below:

spech_helper.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
RSpec.configure do |config|
  ...
  config.treat_symbols_as_metadata_keys_with_true_values = true

  config.around(:each, :vcr) do |example|
    name = example.metadata[:full_description]
      .split(/\s+/, 2)
      .join("/")
      .gsub(/[^\w\/]+/, "_")
    VCR.use_cassette(name, record: :new_episodes) do
      example.call
    end
  end
  ...
end
...

Note: More info on the method chaining trick used above.

These integration tests are making API calls. VCR captures and replays the response on subsequent test runs.

The code above allows me to pass :vcr to the example when I want the HTTP response captured by VCR.


2. Proxy

I have also used around hooks for proxing in my tests. If you want to do any type of scale testing with real data, you can mask your IP to collect the information.

Here’s the typical setup for doing such a thing:

1
2
3
4
5
6
7
it "masks my ip to visit google" do
  tor = Tor.new
  tor.proxy_mechanize do
    visit 'http://www.google.com'
    page.should have_content "Gmail"
  end
end

My setup:

1
2
3
4
it "masks my ip to visit google", :proxy do
  visit 'http://www.google.com'
  page.should have_content "Gmail"
end

Here’s the spec_helper.rb file that allows me to do this:

spec_helper.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
RSpec.configure do |config|
  ...
  tor = Tor.new

  config.treat_symbols_as_metadata_keys_with_true_values = true

  config.around(:each, :proxy) do |example|
    tor.proxy_mechanize do
      example.call
    end
  end
  ...
end
...

I have also combined these hooks to store the response of a proxied request.

1
2
3
4
5
6
...
it "masks my ip and stores the response", :vcr, :proxy do
  visit 'http://www.google.com'
  page.should have_content "Gmail"
end
...

Thanks for the great question Brett!

Comments