Introducing anonymous_active_record
ActiveRecord Without a Database?
Replacement for broken Class.new(ActiveRecord::Base)
.
Very useful in testing Rails apps, and even more so for testing gems without having to specify full blown models.
If you prefer an exceptionally hacky alternative that could also be used for real runtime code, see my other gem activerecord-tablefree!
Installation
Add this line to your application’s Gemfile:
gem 'anonymous_active_record'
And then execute:
$ bundle
Or install it yourself as:
$ gem install anonymous_active_record
Usage
Require the library in your spec_helper
or other test suite boot file.
require 'anonymous_active_record'
Let’s say you want to write specs for a module, HasBalloon
, which provides a method has_balloon?
, and will be mixed into ActiveRecord classes.
module HasBalloon
def has_balloon?
name == 'Spot' ? true : false # only Spot has a balloon
end
end
This won’t work (really!):
let(:ar_with_balloon) do
Class.new(ActiveRecord::Base) do
attr_accessor :name
include HasBalloon
def flowery_name
"#{b_f}#{name}#{b_f}"
end
def b_f
has_balloon? ? '🎈' : '🌸'
end
end
end
So do this instead:
let(:ar_with_balloon) do
AnonymousActiveRecord.generate(columns: ['name']) do
include HasBalloon
def flowery_name
"#{b_f}#{name}#{b_f}"
end
def b_f
has_balloon? ? '🎈' : '🌸'
end
end
end
it 'can test the module' do
expect(ar_with_balloon.new(name: 'Spot').flowery_name).to eq('🎈Spot🎈')
expect(ar_with_balloon.new(name: 'Not Spot').flowery_name).to eq('🌸Not Spot🌸')
end
Generate Options
AnonymousActiveRecord.generate(
table_name: 'a_table_name',
# if table_name is not set klass_basename will be used to derive a unique random table_name
# default is a unique random table name
klass_basename: 'anons', # is default
columns: ['name'],
# default is [],
# meaning class will have ['id', 'created_at', 'updated_at'], as the AR defaults
timestamps: true, # is default
connection_params: { adapter: 'sqlite3', encoding: 'utf8', database: ':memory:' } # is default
) do
# code which becomes part of the class definition
end
The block is optional.
Factory Options
AnonymousActiveRecord.factory(
source_data: [{name: 'Phil'}, {name: 'Vickie'}],
# Array of hashes, where each hash represents a record that will be created
# ... The rest of the options are the same as for generate, see above.
) do
# same as for generate, see above.
end
The block is optional.
There is also a factory!
method that will raise if the create fails, accomplished by calling create!
instead of create
.
comments powered by Disqus