#158
Apr 20, 2009

Factories not Fixtures

Fixtures are external dependencies which can make tests brittle and difficult to read. In this episode I show a better alternative using factories to generate the needed records.
Tags: testing tools
Download (22.9 MB, 12:36)
alternative download for iPod & Apple TV (15.7 MB, 12:36)

Resources

sudo rake gems:install RAILS_ENV=test
# config/environments/test.rb
config.gem "thoughtbot-factory_girl", :lib => "factory_girl", :source => "http://gems.github.com"

# spec_helper.rb
require File.dirname(__FILE__) + "/factories"

# spec/factories.rb
Factory.define :user do |f|
  f.sequence(:username) { |n| "foo#{n}" }
  f.password "foobar"
  f.password_confirmation { |u| u.password }
  f.sequence(:email) { |n| "foo#{n}@example.com" }
end

Factory.define :article do |f|
  f.name "Foo"
  f.association :user
end

# user_spec.rb
describe User do
  it "should authenticate with matching username and password" do
    user = Factory(:user, :username => 'frank', :password => 'secret')
    User.authenticate('frank', 'secret').should == user
  end
  
  it "should not authenticate with incorrect password" do
    user = Factory(:user, :username => 'frank', :password => 'secret')
    User.authenticate('frank', 'incorrect').should be_nil
  end
end

RSS Feed for Episode Comments 67 comments

1. Roman Apr 20, 2009 at 01:30

Thank you, Ryan. You read my mind. I just wanted to read about Factory Girl. :-)


2. Jeffrey Lee Apr 20, 2009 at 08:46

How would you go about sequencing a specific number length? For example, if I need a 7 digit number, how could I specify that the number must have leading zeros?

I'm currently doing:

http://pastie.org/452428

while this works, it certainly isn't ideal. I'd rather have an option such as :length => 7 that would produce: 0000001, 0000002, etc.


3. Jeffrey Lee Apr 20, 2009 at 08:55

To answer my own question, you can use sprintf to get leading zeros.

http://pastie.org/452449


4. Dan Croak Apr 20, 2009 at 10:16

Excellent screencast as usual.

You can use Machinist's or Object Daddy's syntax from within Factory Girl if you like either of those styles better:

http://giantrobots.thoughtbot.com/2009/2/17/factory_girl-1-2-adding-excitement-to-stale-factories

http://dev.thoughtbot.com/factory_girl/classes/Factory/Syntax.html


5. jnstq Apr 20, 2009 at 14:31

Thanks for great episode! I have a command in my TextMate bundle for generating factory code for a model in the database. It will build attributes with default values from database if present. It's up on github, http://github.com/jnstq/rubyeqp/tree/master. A real time saver.


6. andy Apr 20, 2009 at 16:05

Great screencast. But I am left wondering - why would you want to do this? It looks to me like factory girl is more complicated than using fixtures.


7. George Apr 20, 2009 at 20:38

Thanks Ryan. Good post.


8. Jeff Dean Apr 20, 2009 at 21:08

Thanks! I've been using object mother patterns on all my apps for several months now, and although they are slower, the increase in readability and maintenance more than makes up for it.

My favorite object mother gem by far is Fixjour - http://github.com/nakajima/fixjour/tree/master - which I now use pretty much exclusively.


9. Josh Apr 21, 2009 at 07:18

Great screencast Ryan! You have an uncanny way of touching on topics that are on my mind.. I hope you can't read all of my thoughts! ;D


10. Ryan Bates Apr 21, 2009 at 08:10

@MadDog and andy, this may seem like needless work up front, but it will result in more maintainable and easier to read tests. Just like any refactoring, you may not see the benefits immediately.

Fixtures can quickly get out of hand as the test suite grows. Once you have 20 different records in a fixtures file of varying attributes trying to get each edge case it becomes difficult to maintain. All of the tests are sharing this same data and no single test really uses all of the records at once.

In short, if you build tests which aren't heavily dependent on external data (fixtures) then they will be much more maintainable and easier to read because everything that is important to that test is in one place.


11. Vishal Apr 22, 2009 at 01:42

Thanks Ryan for this.
But i think a more better option for test would be machinist.
it is very easy to use.
I have used it in my project.


12. Greg Apr 23, 2009 at 09:27

Are there any factories for regular objects? FactoryGirl, Mechanize, ObjectDaddy and Fixjour are great frameworks for ActiveRecord. But sometimes people write code that doesn't use ActiveRecord.


13. Tim Matheson Apr 23, 2009 at 20:51

@Ryan Bates
When defining a new factory, couldn't you just do this to achieve a random value for fields?

Factory define :user do |f|
  f.full_name "Tim Matheson"
  f.email "me@timmatheson#{rand(9999)}.com"
end

Wouldn't that do the same thing? Or is it best to stick with the block as it is more reliable?


14. Luka Apr 25, 2009 at 17:08

which textmate theme are you using?


15. James B. Byrne Apr 26, 2009 at 18:18

@ Greg
> Are there any factories for
> regular objects?

What would a "regular object factory" provide that factory_girl or machinist does not?


16. andy Apr 27, 2009 at 08:39

@ryan - thanks for your response!

does anyone have any guidelines on when to use factories vs mocks?

i am planning to use factories for unit tests, and mocks for controllers, and 'composite objects'. does that sound like a good strategy?


17. Vadim May 26, 2009 at 02:49

Thank you for the excellent article, for you became on one subscriber anymore


18. Justin Charles Beck Jun 12, 2009 at 13:06

Great screencast. Thanks so much!


19. Sig Jun 16, 2009 at 00:56

Hello Ryan,
great screencast as always.
I'm trying to update the user factory you have created on this episode in order to handle password_hash and password_salt (when the user inputs his/her password).

Any ideas about how to deal with this issue?

Thanks and have a good 1!


20. David Johnson Jun 23, 2009 at 22:34

Anyone have any links to using stubs from Factory_Girl, I can't seem to get it to work. I have inherited code where the models have a dependency of A belongs to B which belongs to A prime (polymorphic).

Think sales person belongs to a region which has a manager (which is just a polymorphic version of the [sales]Person table). With fixtures it "auto" built the tables so I didn't need to worry about initial validations, I can't figure out how to do that with Factories.


21. Justin Jun 25, 2009 at 15:14

How do you resolve circular associations in factories? I have an account that contains a collection of users one of which is the account owner:

Factory.define :account do |f|
  f.state "pending"
  f.association :owner, :factory => :user
end

Factory.define :user do |f|
  f.sequence(:first_name) { |n| "factory_user#{n}" }
  f.last_name "Smith"
  f.password "test"
  f.password_confirmation { |u| u.password }
  f.email { |a| "#{a.first_name}@example.com".downcase }
  f.eula "1"
  f.association :account
end

It loops in to infinity and crashes the tests... Is there an obvious way around this? Thanks for your help and thanks for a great set of casts.


22. Anime Jul 14, 2009 at 04:35

Thanks Ryan. Good job.


23. çizgi film oyunları Aug 23, 2009 at 14:14

Good article, thanks to the author to share


24. filmy online Aug 29, 2009 at 06:44

Very nice screencast. Thank you so much!


25. G-man Sep 21, 2009 at 21:19

Since this project seems to use restful_authentication, and the newer episodes have moved to authlogic, I have been refactoring this tutorial to work with authlogic -- a good way to learn!


26. IdahoEv Nov 04, 2009 at 22:19

I'm pretty fed up with Factories, and specifically Factory Girl.

Yes, they can make for easier-to-read tests. But they're a lot slower than fixtures, and Factory Girl is so poorly documented that they waste huge amounts of my coding time. In some cases, it's also very inflexible, and things that would be easy to do with fixtures are very hard to do with Factory Girl.

Example: try finding the documentation for how to create a simple has_many relationship. Say, Topic has_many Posts, such that your default factory for Topic creates one with three simple posts.


27. ffxiv gil Apr 27, 2010 at 22:04

i like it


28. mise May 03, 2010 at 20:58

This post is beyond awesome.


29. cell phone spy May 06, 2010 at 06:49

This is a great post you have written. Having this information will prove to be very useful going forward.


30. catch cheating spouse May 06, 2010 at 06:54

This is a great post you have written. Having this information will prove to be very useful going forward. Thanks.


31. android parental control May 06, 2010 at 06:55

Very useful site and post.


32. parental control windows xp May 06, 2010 at 06:56

Thank you for this information. I can use it often.


33. ugg australia uk May 17, 2010 at 17:19

Thank you for sharing the good information.hope that you'll share more to your readers.


34. ugg boots outlet May 31, 2010 at 18:58

Well done!


35. mbt outlet May 31, 2010 at 19:00

Wonderful,thanks for taking your time to update this useful post .


36. james Jun 09, 2010 at 22:35

Thank you for sharing this! It is very interesting!


37. Gucci outlet store Jun 18, 2010 at 08:12

sorry,i can't understand.


38. laptop charger Jun 22, 2010 at 22:55

Thank you for your better alternative using factories to generate the needed records. Your shoe is very good.


39. ugg boots outlet Jun 23, 2010 at 00:16

I learned some knowledge and experience.


40. permatec Jun 24, 2010 at 06:19

Very nice tutorial :)


41. Sam Jul 03, 2010 at 15:02

Any body have any 2 cents on when is a good time to use Factory.stub? Just curious. Thx.


42. watch twilight eclipse online Jul 03, 2010 at 22:00

Twilight, a fantasy romance involving a self-loathing vampire and his sweet-blooded soul mate, is the kind of movie that gets pop culture addicts excited. Surrender to its daftness and you’ll emerge covered in something very like a cold sweat.


43. watch inception online Jul 03, 2010 at 22:02

I have now watch two trailers for this film and I still have absolutely no idea what it is about....looks awesome though! .


44. watch salt online Jul 03, 2010 at 22:03

Thank you!!! as much i appreciate the hard working actors, that was a laaaame move, her elbow was nowhere near his face!!! But I’m still watching it.


45. Austin Cosmetic Dentist Jul 05, 2010 at 08:54

Lovely code. I must say you are a good coder. It really works nicely.


46. mbt shoes sale Jul 08, 2010 at 03:07

welcome to buy mbt healthy shoes


47. Watch Resident evil afterlife online Jul 09, 2010 at 01:58

Thank you ryan


48. Resident evil afterlife online Jul 09, 2010 at 01:59

I just download your code for my purpose.


49. Resident evil afterlife Jul 09, 2010 at 01:59

Thanks for your source code.


50. Watch Resident evil afterlife online free Jul 09, 2010 at 02:00

Excellent alternate resource ryan.


51. Resident evil afterlife movie download Jul 09, 2010 at 02:02

i like to go with machinist resource.


52. Football Jerseys Jul 12, 2010 at 23:13

it's very useful for me.


53. Predictii Tenis Jul 19, 2010 at 07:05

Useful,thanks.


54. iPhone Ringtone Maker for mac Jul 20, 2010 at 19:11

this is thank you for sharing the post


55. skype phone Jul 21, 2010 at 01:45

useful code...Thank you


56. flowers Jul 23, 2010 at 23:16

Really like this website, this really helps and very useful.
I love flowers...I am also interested to send flowers all over the world....


57. coach pureses Jul 27, 2010 at 19:32

Coach is a world brand, product quality is good, it is a kind of fashion.


58. web production process Jul 28, 2010 at 03:06

Resources like the one you mentioned here is very useful! I will post a link to this page on my blog. I am sure my visitors will find that very useful.


59. usb phone world Jul 29, 2010 at 02:09

very helpful code..thank you


60. leatherbhandbags Aug 02, 2010 at 02:23

i like coach


61. vibram five fingers Aug 04, 2010 at 00:46

Well said. I never thought I would agree with this opinion, but I’m starting to view things from a different view. I have to research more on this as it seems very interesting. One thing I don’t understand though is how everything is related together.


62. Golden Retriever Training Aug 04, 2010 at 02:22

Fantastic post


63. fashion handbags Aug 05, 2010 at 20:37

it is a very good post


66. louis vuitton mahina Aug 07, 2010 at 01:10

I think its a pretty good idea not that there aren't other sites out there that already do something similar but I think it might catch on here pretty well.


66. fashion uggs Aug 08, 2010 at 01:21

There is one more site that I have visited, provide me information that is really unique and the service that they offer also I have experienced, really I enjoy this sevice so I request others please visite this and I want to tell you that after enjoying this service you’ll enjoy it again and again its .


67. bamboo furniture Aug 08, 2010 at 16:38

Great!This article is creative,there are a lot of new idea,it gives me inspiration.I think I will also inspired by you and think about more new ideas


67. elma sirkesinin faydalari Aug 09, 2010 at 09:54

Thank you for the excellent article, for you became on one subscriber anymore


68. fashion handbags/leather bags Aug 10, 2010 at 01:24

thank you for your post


69. moncler jacket Aug 11, 2010 at 07:41

that is very kind of you to post this for us, thank you very much.


70. webcam videooo Aug 11, 2010 at 19:24

Thanks Ryan. Good job.


71. ugg calssic short Aug 18, 2010 at 02:36

The more difficulties we encounter, the harder we should work.


72. ugg black|pink|chestnut|grey|sand|chocolate Aug 18, 2010 at 05:34

A lot of people will have to work together, so with the development of society a lot of jobs are being created.


73. backpack,luggage,laptop bag Aug 18, 2010 at 20:42

<a target="_blank" href="http://www.slibag.com/">backpack,luggage,laptop bag</a>


74. vibram five fingers Aug 18, 2010 at 21:40

I recently came across your blog and have been reading along.
I thought I would leave my first comment. I don’t know what to say except that I have enjoyed reading.Nice blog,I will keep visiting this blog very often.


75. Wholesale hats Aug 20, 2010 at 20:36

Good post. I am also going to write a blog post about this...I enjoyed reading your post and I like your take on the issue. Thanks.


76. Nike Sb Dunks Aug 22, 2010 at 23:18

Thanks! This is truly fantastic stuff - thank you too your knowledge. We share the opinion on and I really enjoy reading your article. Web proliferation of new developments in the field of design and entrepreneurial spirit of people


77. Marty Phlipmann Aug 24, 2010 at 09:50

This one was a little difficult to follow because you never tell us about when something is magic. For instance when you use the factory to create a user name an password is it magic that it uses your username and password or did it ignore it and create them using the "foo" name? When you test for the name and pass you provided it passes so I THINK it's using magic but I'm not sure. Especially since you specifically use the user.password for the verification thing.

It would seem to make more sense (if it isn't using magic) to do a: f.username = user.username || "Foo". But again it might already be doing that for us.

So, in the future, PLEASE point out the magic bits so it makes more sense. I've noticed you breeze over them a lot in all of your casts. Hopefully you accept this as constructive criticism.

Anyway, thanks a ton for the 'casts. They have been a great help in learning ruby and rails.


78. Wholesale Electronics Aug 25, 2010 at 02:04

Discount Wholesale Electronics, Wholesale Cell Phones, Electronic Gadgets and More from the Best Dropship Wholesaler


79. louis vuitton shoes Aug 26, 2010 at 23:14

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


80. wholesale Laser Aug 30, 2010 at 20:02

thanks for your article, it is so good.


81. snow boots Aug 30, 2010 at 21:03

But I am left wondering - why would you want to do this? It looks to me like factory girl is more complicated than using fixtures.


82. itunes gift cards,itunes store Sep 01, 2010 at 00:38

http://www.itunes-gift-cards.net itunes gift cards,itunes store


83. itunes gift cards,itunes store Sep 01, 2010 at 00:39

<a href=http://www.itunes-gift-cards.net title=itunes gift cards,itunes store><h1>itunes gift cards,itunes store</h1></a>


84. louis vuitton sunglasses Sep 01, 2010 at 21:22

I feel like I’m often looking for interesting things to read about a variety of subjects, but I manage to include your blog among my reads every day because you have interesting entries that I look forward to. Here’s hoping there’s a lot more great material coming!


85. vibram five fingers Sep 02, 2010 at 01:34

Well said. I never thought I would agree with this opinion, but I’m starting to view things from a different view. I have to research more on this as it seems very interesting. One thing I don’t understand though is how everything is related together.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source