Skip to content

Instantly share code, notes, and snippets.

@dwmoore
Created January 10, 2018 17:05
Show Gist options
  • Save dwmoore/fadb3cea9c5e2e91f61c08ca24669867 to your computer and use it in GitHub Desktop.
Save dwmoore/fadb3cea9c5e2e91f61c08ca24669867 to your computer and use it in GitHub Desktop.
Testing Ruby modules included on and making use of ActiveRecrord Model functionality in RSpec
# Recently I had need to work on an ActiveRecord model
# that gained much of its functionality through the
# inclusion of a Ruby Module. Over the course of the
# work, I found that many of the models that include
# the module also included duplicated specs to cover
# the inherited behavior.
#
# Of course, this isn't ideal.
#
# In a perfect world, the module's behavior would be
# exercised in isolation. It would have its own spec
# file and specs and allow removal of all the similar
# specs on the including models. Unfortunately, most
# Rails apps don't have a generic model just lying
# around to function as a stand-in in testing
# situations such as this.
#
# The solution: Build an ActiveRecord model with the
# required attributes and methods at spec runtime.
#
# Thanks to Foraker Labs and user hjing on
# StackOverflow for filling in the gaps!
#
# https://www.foraker.com/blog/testing-activerecord-modules
# https://stackoverflow.com/questions/14431723/activemodelvalidations-on-anonymous-class
#
require "spec_helper_rails"
describe SomeNamespace::SomeModuleToTest do
let(:mock_class) { build_mock_class }
let!(:record) { mock_class.create(some_required_attribute: 1) }
before(:all) { create_table }
after(:all) { drop_table }
describe "some behavior" do
it "does a thing" do
# ...
end
end
def build_mock_class
Class.new(ActiveRecord::Base) do
self.table_name = "mock_table"
reset_column_information
include SomeNamespace::SomeModuleToTest
# Required to prevent ArgumentError within AR
def self.name
"MockClass"
end
end
end
def create_table
ActiveRecord::Base.connection.create_table :mock_table do |t|
t.integer :some_required_attribute
end
end
def drop_table
ActiveRecord::Base.connection.drop_table :mock_table
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment