Created
January 10, 2018 17:05
-
-
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
This file contains 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
# 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