Created
September 11, 2015 15:55
-
-
Save mattbrictson/72910465f36be8319cde to your computer and use it in GitHub Desktop.
Using vcr with Minitest + Rails (test unit style)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
group :test do | |
gem "minitest" | |
gem "vcr" | |
gem "webmock", "~> 1.15.0" | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# test/test_helper.rb | |
# Load everything from test/support | |
Dir[File.expand_path("../support/**/*.rb", __FILE__)].each { |rb| require(rb) } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# test/support/vcr.rb | |
require "vcr" | |
VCR.configure do |config| | |
config.allow_http_connections_when_no_cassette = false | |
config.cassette_library_dir = File.expand_path("../../cassettes", __FILE__) | |
config.hook_into :webmock | |
config.ignore_request { ENV["DISABLE_VCR"] } | |
config.ignore_localhost = true | |
config.default_cassette_options = { | |
:record => :new_episodes | |
} | |
end | |
# Monkey patch the `test` DSL to enable VCR and configure a cassette named | |
# based on the test method. This means that a test written like this: | |
# | |
# class OrderTest < ActiveSupport::TestCase | |
# test "user can place order" do | |
# ... | |
# end | |
# end | |
# | |
# will automatically use VCR to intercept and record/play back any external | |
# HTTP requests using `cassettes/order_test/_user_can_place_order.yml`. | |
# | |
class ActiveSupport::TestCase | |
def self.test(test_name, &block) | |
return super if block.nil? | |
cassette = [name, test_name].map do |str| | |
str.underscore.gsub(/[^A-Z]+/i, "_") | |
end.join("/") | |
super(test_name) do | |
VCR.use_cassette(cassette) do | |
instance_eval(&block) | |
end | |
end | |
end | |
end |
Thanks Matt! I use the same approach now and it works perfectly well 👍
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Since I wrote this gist 6 years ago I have moved to a different technique. I now use a module that defines a
with_expiring_vcr_cassette
method and explicitly include that module in my test classes where I want vcr. Then I'll wrap the code within an test withwith_expiring_vcr_cassette
.I'm not sure that solves the problems you mentioned with the monkey patch, but it has been serving me well.
My preference nowadays is exclude cassettes from git and expire them periodically so they get regenerated. That way most tests are fast (using the cassettes as sort of cache), but they will regularly get refreshed so I can be sure that the actual end-to-end HTTP calls continue to get exercised. This helps guard against an API change in the external system that I would not notice if the cassettes were permanently recorded.