HasMockObjects

After reading Practical Object-Oriented Design in Ruby: An Agile Primer by Sandi Metz, I wanted an easy way to put off making decisions about related objects during the early phases of a project. This is what I came up with for that.

I wanted a very simple syntax for saying, "I know I will want this object to the associated with this other thing, but I don't yet know what columns or methods it will really need." Also known as the Fake-It-Until-You-Make-It method.

I also wanted something very simple to search for in a project top see where and how it is being used, since something like this is only useful at early stages and would be replaced over time with the actual implementation of the things it is faking.

Installation

gem install has_mock_objects

Usage

Call the method has_mock_objects in any ActiveRecord model. That will add two methods to the model that allows you pretend you have associated objects.

class Book < ActiveRecord::Base
  has_mock_objects

  attr_accessible :description, :title

  has_many_mocks :chapters, 5, title: :words, content: :paragraphs  #returns 0 to 5 Chapters
  has_many_mocks :testimonials, 10, testify: :words #returns 0 to 10 Testimonials
  has_one_mock :author, name: :name, email: :email #returns 1 Author
  has_many_mocks :bibliographies, 4..5, name: :words, content: :paragraph #returns 4 to 5 Bibliographies

  validates :title, presence: true, uniqueness: true

end

Any instance of Book would respond to chapters, returning an array of OpenStruct Chapter objects, randomly generatingfrom 0 up to 5 of them, and they would each have a title attribute and content, with each of those generated by Faker using the methods specified.

This makes it possible to do this in a view:

<h2>Chapters(<%= @book.chapters.count %>)</h2>
<ul>
  <% @book.chapters.each do |chapter| %>
    <li>
      <h4><%= chapter.title %></h4>
      <p><%= chapter.content %></p>
    </li>
  <% end -%>
</ul>

And since the chapters are stored in an attribute on the instance the @book.chapters.count will not change until the instance is instantiated again (the page is refreshed). This allows a page refresh to show you different configurations of text and counts, giving you a chance to see if truncation might be needed on the chapter.content attributes, for example.

The call to has_one_mock works similarly, but always returns a single OpenStruct object (no chance of nil).

Not every Faker method is currently supported. In an effort to simplify the syntax as much as possible, a constant is defined for these methods with their corresponding Faker equivalent:

word: Faker::Lorem.word
words: Faker::Lorem.words.join(' ')
sentence: Faker::Lorem.sentence
sentences: Faker::Lorem.sentences.join(' ')
paragraph: Faker::Lorem.paragraph
paragraphs: Faker::Lorem.paragraphs.join(' ')
name: Faker::Name.name
first_name: Faker::Name.first_name
last_name: Faker::Name.last_name
phone_number: Faker::PhoneNumber.phone_number
email: Faker::Internet.email
credit_card_number: Faker::Business.credit_card_number
credit_card_type: Faker::Business.credit_card_type

Additionally, methods to return Time Objects have been added:

today: always returns Time.now
recent_date: Returns a Time Object set sometime within the last year
historical_date: Returns a Time Object set sometime within the last decade

License

Copyright (c) 2013 Carl Anderson, released under the MIT license

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.