ActiveMocker
Create mocks from active record models without loading rails or running a database.
Installation
Add this line to your application's Gemfile:
gem 'active_mocker'
And then execute:
$ bundle
Or install it yourself as:
$ gem install active_mocker
Usage
#db/schema.rb
ActiveRecord::Schema.define(version: 20140327205359) do
create_table "people", force: true do |t|
t.integer "account_id"
t.string "first_name", limit: 128
t.string "last_name", limit: 128
t.string "address", limit: 200
t.string "city", limit: 100
end
end
#app/models/person.rb
class Person < ActiveRecord::Base
belongs_to :account
def bar(name, type=nil)
puts name
end
def self.bar
end
end
require 'active_mocker'
ActiveMocker.configure do |config|
# Required Options
config.schema_file = "#{APP_ROOT}/db/schema.rb"
config.model_dir = "#{APP_ROOT}/app/models"
# Additional Options
config.schema_attributes = true #default
config.model_attributes = true #default
# Logging
config.log_level = Logger::WARN #default
end
ActiveMocker.mock('Person')
=> PersonMock
PersonMock.column_names
=> ["account_id", "first_name", "last_name", "address", "city"]
person_mock = PersonMock.new(first_name: "Dustin", last_name: "Zeisler", account: ActiveMocker.mock('Account').new)
=> #<PersonMock @first_name="Dustin", @last_name="Zeisler">
person_mock.first_name
=> "Dustin"
When schema.rb changes, the mock fails
#db/schema.rb
ActiveRecord::Schema.define(version: 20140327205359) do
create_table "people", force: true do |t|
t.integer "account_id"
t.string "f_name", limit: 128
t.string "l_name", limit: 128
t.string "address", limit: 200
t.string "city", limit: 100
end
end
person_mock = PersonMock.new(first_name: "Dustin", last_name: "Zeisler", account: AccountMock.new)
=> NoMethodError: undefined method `first_name=' for #<PersonMock:0x007f860abf6b10>
Mocking instance and class methods
person_mock.bar
=> ArgumentError: wrong number of arguments (0 for 1..2)
person_mock.bar('baz')
=> RuntimeError: #bar is not Implemented for Class: PersonMock
person_mock.mock_instance_method(:bar) do |name, type=nil|
"Now implemented with #{name} and #{type}"
end
person_mock.new.bar('foo', 'type')
=> "Now implemented with foo and type"
person_mock.mock_class_method(:baz) do
"Now implemented"
end
When the model changes, the mock fails
#app/models/person.rb
class Person < ActiveRecord::Base
belongs_to :account
def bar(name)
puts name
end
end
person_mock.new.bar('foo', 'type')
=> ArgumentError: wrong number of arguments (2 for 1)
app/models/person.rb
class Person < ActiveRecord::Base
belongs_to :account
def foo(name, type=nil)
puts name
end
end
person_mock.mock_instance_method(:bar) do |name, type=nil|
"Now implemented with #{name} and #{type}"
end
=> NameError: undefined method `bar' for class `PersonMock'
ActiveRecord supported methods
Class methods
- create/new
- column_names
- find
- find_by
- find_by!
- find_or_create_by
- find_or_initialize_by
- where - (only supports hash input)
- delete_all/destroy_all
- all
- count
- first/last
Instance methods
- attributes
- update
- save
- write_attribute - (private)
- read_attribute - (private)
Collection Associations
- last/first
- sum(attribute)
- <<
- Enumerable methods
Known Limitations
- ::mock model names and table names must follow the default ActiveRecord naming pattern.
- Included/extended module methods will not be included on the mock.
Inspiration
Thanks to Jeff Olfert for being my original inspiration for this project.
Contributing
- Fork it ( http://github.com/zeisler/active_mocker/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request