Skip to content

Instantly share code, notes, and snippets.

@diegodurs
Last active August 29, 2015 13:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diegodurs/10712996 to your computer and use it in GitHub Desktop.
Save diegodurs/10712996 to your computer and use it in GitHub Desktop.
Attempt to mock basic features of ActiveRecord.I'm willing to include ActiveModel::Dirty, but I do not want to specify my model attributes for every models.
require 'ostruct'
require 'forwardable'
class MockActiveRecord < OpenStruct
def save(opts); end
alias_method :save!, :save
def attributes
to_h.symbolize_keys
end
def attributes=(values)
values.each do |k,v|
send("#{k}=",v)
end
end
class << self
extend Forwardable
def_delegators :@collection, :count, :first, :last
def transaction
yield if block_given?
end
def create(attributes = {}, &blk)
object = new(attributes)
if block_given?
if blk.arity == 1
yield object
else
object.instance_eval(&blk)
end
end
collection << object
return object
end
alias_method :create!, :create
def pluck(attribute)
collection.map { |o| o.send(attribute) }
end
def find(id)
collection.each do |object|
return object if object.id == id
end
return nil
end
def destroy_all
@collection = []
end
private
def collection
@collection ||= []
end
end
end
require 'support/models/mock_active_record'
describe MockActiveRecord do
describe '::create' do
context 'given a block with arity 1' do
it 'should create an object' do
object = MockActiveRecord.create do
self.title = 'Hello World'
end
expect(object.title).to eq 'Hello World'
expect(MockActiveRecord.last).to eq object
end
end
context 'given a block with arity 0' do
it 'should create an object' do
object = MockActiveRecord.create do |t|
t.title = 'Hello World 2'
end
expect(object.title).to eq 'Hello World 2'
expect(MockActiveRecord.last).to eq object
end
end
context 'given a hash of attributes' do
it 'should create an object' do
object = MockActiveRecord.create(title: 'Hello World 3')
expect(object.title).to eq 'Hello World 3'
expect(MockActiveRecord.last).to eq object
end
end
end
describe '::pluck' do
it 'should return an array of value' do
MockActiveRecord.create(title: 'Hello World 1')
MockActiveRecord.create(title: 'Hello World 2')
expect(MockActiveRecord.pluck(:title)).to include *[
'Hello World 1', 'Hello World 2'
]
end
end
describe '::destroy_all' do
it 'should reset the collection' do
MockActiveRecord.create(title: 'Hello World 1')
expect(MockActiveRecord.count).to be > 1
MockActiveRecord.destroy_all
expect(MockActiveRecord.count).to eq 0
end
end
describe "::find" do
it 'should return nil when no id found' do
expect(MockActiveRecord.find(3)).to be_nil
end
it 'should return the correct object' do
id_1 = MockActiveRecord.create(id: 1)
id_2 = MockActiveRecord.create(id: 2)
expect(MockActiveRecord.find(1)).to eq id_1
expect(MockActiveRecord.find(2)).to eq id_2
end
end
describe 'class collection' do
it 'should not collide' do
UserMock = Class.new(MockActiveRecord)
ClientMock = Class.new(MockActiveRecord)
UserMock.create(name: "Foo")
ClientMock.create(name: "Bar")
expect(MockActiveRecord.pluck(:name)).to_not include *['Foo', 'Bar']
expect(UserMock.pluck(:name)).to eq ['Foo']
expect(ClientMock.pluck(:name)).to eq ['Bar']
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment