Having used Webmock and VCR in past projects, there have been times when I'd spawn an instance of Sinatra, just to hit an API end-point, but this is certainly a better way to go about it.
module FakeMovieFacts
class Application < Sinatra::Base
get "/movies/:movie_name/actors" do
{
actors: [
{
name: "Actor 1",
character_played: "Character 1"
},
{
name: "Actor 2",
character_played: "Character 2"
}
]
}.to_json
end
end
end
Initialize this as a new gem with bundle gem fake_movie_facts
and extract FakeMovieFacts::Application
(above) into fake_movie_facts/lib/fake_movie_facts/application.rb
and add a config.ru
file to the root of the repo
# config.ru
$LOAD_PATH << File.expand_path("../lib", __FILE)
require "fake_movie_facts/application"
run FakeMovieFacts::Application
You can either run this locally via the rackup
command, or deploy to Heroku. Suppose you want to hit your fake API in development, consider an adapter in your main application
# app/models/movie_database.rb
class MovieDatabase
cattr_accessor :base_url
self.base_url = ENV.fetch("MOVIE_FACTS_API_BASE_URL")
def actors_for(movie:)
HTTParty.get(self.base_url + "/movies/#{movie.id}/actors", format: :json)
end
end
Had you spawned the fake API locally, your main app could be booted as $ MOVIE_FACTS_API_BASE_URL=localhost:4567 rails server
, or point at the Heroku instance MOVIE_FACTS_API_BASE_URL=http://fake-movie-facts.herokuapp.com
.
It's worth reading the full article which considers extra challenges when faking APIs in staging, should the need arise.