Last active
August 29, 2015 13:59
-
-
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.
This file contains hidden or 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
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 |
This file contains hidden or 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
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