anoiaque / factory_boy_1

Create fixtures for unit testing as in Factory Girl but without database usage.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Overview

Factory_boy aims to avoid slow unit tests due to usage of create/find fixtures in database, with factory_girl for example. Factory_boy can be used as factory_girl except that factories are not created in database. ActiveRecord::Base find method is stubbed to return fixtures (plants) you have instanciate. Differenciate find :all, :first, :last, but doesn’t do the work of find with sql conditions. Anyway we don’t think it’s important for unit test, if some find calls with sql conditions, :include … etc have to be tested, report it in integration tests is a better idea.

See some examples below. You can see also unit tests / code for deeper comprehension.

Install

gem install factory_boy

Basic Usage

Define your Plants (=~ Factories if factory_girl) in test/plants.rb

Example :

Plant.define :user do |user|
 user.name="Bart"
 user.age=800
end

Get it with :

user = Plant(:user)

Example of tests :

def test___1
  user = Plant(:user)
  assert_equal user, User.find #OK
  assert_equal user, User.find(:first) #OK
  assert_equal user, User.find(:last) #OK
end

def test___2
  2.times { Plant(:user) }
  assert_equal 2, User.find(:all).size #OK
end

You can also create a particular plant of user like that:

user = Plant(:user, :name => "Marie", :age => age)

Specification of the class of the fixture definition

Plant.define :admin, :class => User do |user|
  user.name  = "Bart"
  user.age = 800
end

Associations

Assign fixtures to association in definition of plant :

Plant.define :profile do |profile|
  profile.password = "BREIZH!"
end

Plant.define :adress do |adress|
  adress.number = 12
  adress.street = "rue de Brest"
end

Plant.define :user do |user|
  user.name  = "Bart"
  user.age = 800
  user.profile = Plant.association(:profile)
  user.adresses = [Plant.association(:adress)]
end

Definitions with dependent attributes

If you want to use the value of another attribute in definition, do like that :

Plant.define :user do |user|
  user.name = "Marie"
  user.adresses = [Adress.new(:street => "Rue de #{user.name}")]
end

Sequences

As with factory_girl you are able to use sequences, like that :

Plant.sequence :email do |n|
  "incognito#{n}@kantena.com"
end

Plant.next(:email) # => "incognito1@kantena.com"
Plant.next(:email) # => "incognito2@kantena.com"

Dependencies

No dependency. Doesn’t work, for now, with Active Support 3.0 (In development)

In Development

  • Stubs only find of Plant class so we can use both AR find on klasses that are not ‘planted’

  • Plant(:xx).clear

  • Provide an id to each Plant

  • When assign instance to an association(ie profile of user), set foreign_key id (ie profile_id of user)

  • To work with Rails 3 (Active Support 3)

  • Stub find with conditions using Arel( for Rails 3)

Change Log

  • FIX : Push new object in pool of a class doesn’t override objects in pool. Safe push.

  • FIX : Use #clone instead of #dup. Not same behavior with and without rails(may be overriden by active support)

  • FIX : Bug with override TestCase#run under ActiveSupport::TestCase

Notes

Report Bugs here , on github

About

Create fixtures for unit testing as in Factory Girl but without database usage.

License:MIT License


Languages

Language:Ruby 100.0%