How-to: Rails 4.2, FakeS3, AWS SDK2 and Rspec

A quick how-to for setting up the fakes3 gem for development and testing

Working with an existing Rails 4.2 application, I wanted to disconnect from AWS S3 during development and when running tests. Mostly when running tests. One requirement was no refactoring of the existing application source.

Turns out this is exactly what the fakes3 gem (repo) is designed to do. The install is straightforward but does have a series of small steps to connect the dots.

(I was dreading this task but it turned into no big deal. How often does that happen?!)

The Rails app I’m working with is running on Unbuntu 16.04, Ruby 2.2.2, Rails 4.2.5, Rspec 3.4.4, AWS SDK 2 and using the figaro gem to handle environment variables.

Steps to Install

  • Add the gem to the Gemfile and run bundle install:

    We’re adding it to the Gemfile so it will be available to rspec.

  • Decide on a physical location for the storage that’s replacing S3. For this demonstration I’m using /media/fakes3/root.
  • Add DNS entries to /etc/hosts:

    Notice the /etc/hosts entry for a local bucket. My Rails app only uses one fixed bucket so the single entry will work in this case. If you have more than one bucket, you’ll need to add more entries.

    (I’m not sure how this would work if your application is creating and deleting buckets on the fly. Might not be able to use the DNS set-up?)

  • Update your ENV variables for development and testing. If you’re using the figaro gem this goes in the development section of the config/application.yml file:

  • Start the fakes3 server (from the root of your Rails app):

    If you run into an error, the first thing to check is any typos creating a mismatch amongst the three files and the server command.

 

Test the Installation

  • For a quick test, create a rake task with AWS S3 method calls that mimic what’s in your Rails app. Here’s the one I used:

    This is only meant as a quick and dirty check that the server is up and running. The gem has some some built in tests that would be a starting place if more formal testing is needed. In my case, I decided that working Rspec scripts were enough.

 

Integrating into Rspec

And now for the most useful reason to add this gem. The following is based on @cesarandrue’s gist. (Thanks!)

  • Add the file fakes3_server.rb to ./spec/support.

    I made two small changes to the gist source.

    Added a method so the Rspec tests could check if they’re working with fakes3. (Hmm. A future project will be to refactor the specs to not care if it’s fakes3 or AWS S3.)

    I also moved the fakes3 directory under the Rails root tmp directory to it would be excluded by the existing .gitignore.

  • Update Rspec.configure to start and stop the fakes3 server. This will be either spec/rails_helper.rb

 

Done!

It’s nice when something just works. One of my actual use cases was adding this to a Rails engine. Same basic process just working with the test app under the spec directory and a gemspec instead of Gemfile.