
Rails Testing with Factory Girl - eatenbyagrue
http://www.hiringthing.com/2012/08/17/rails-testing-factory-girl.html
======
indrekju
I hate when people are using it in the unit tests. It just makes testing very
convenient, so they start using it everywhere. In the end, the test suite gets
very slow. Unit tests should not hit the database.

First example there: test_new_customer_defaults. Really, it needs 3 saved
models to test this? FactoryGirl isn't solution here. It's just hiding the
problem.

~~~
urbanautomaton
If I could upvote the parent any harder, it would hit orbit.

If you need a complex network of collaborators to test a method, the answer is
not to obscure the creation of those collaborators, it's to refactor so that
each object talks only to its immediate neighbours, and then stub the heck out
of them. If it absolutely has to be something that acts like an ActiveModel,
then use mock_model().

~~~
samd
And I'd upvote it to Mars. FactoryGirl is completely an anti-pattern, unless
maybe you're doing acceptance testing, but you know even then I wouldn't want
FactoryGirl in my codebase, people would be too damn tempted to use it
everywhere.

~~~
mattgreenrocks
That's where we find ourselves currently: constructing 3-4 levels out due to
Law of Demeter violations, and it becomes incredibly brittle when seemingly
unrelated classes change.

IMO, DHH (and others) argue too hard against core OO principles (like SRP and
LoD) that have the possibility of helping out when the domain model becomes
more complex. "Just use Rails" is fine when spinning up, but as the app grows,
it becomes increasingly less pleasant. Coupling increases in the name of less
code.

Ideas like hexagonal architecture look nice, but I'm left wondering how to
implement them when the framework insists on infecting core domain classes
(AR::Base).

~~~
sanderjd
As an FYI to your last point - in Rails master (which will be Rails 4), you
can active-record-ify a class by including ActiveRecord::Model, rather than
inheriting from ActiveRecord::Base. In fact, that is all ActiveRecord::Base
does itself -
[https://github.com/rails/rails/blob/master/activerecord/lib/...](https://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb#L324).

~~~
mattgreenrocks
But your core domain classes are still coupled to their persistence mechanism
in the name of 'pragmatism.'

~~~
sanderjd
Who says they have to be? That's a design decision. There is literally nothing
(besides maybe inertia?) that enforces that "rule".

------
sanderjd
A response from a naysayer:

 _Factories are slow._ Yes, they really are. Persisting everything along a
chain of associations will _always_ be slower than properly isolating the
dependencies of the unit under test, SSD or not. It's easier to enjoy Ruby
when not constantly waiting minutes for tests to run.

 _Factories increase the over-all complexity of your app._ Are you kidding me?
Yes, they _do_. Expertise and huge, easy gains have nothing to do with
reducing complexity and more often (but not always) increase it. A test suite
where every test depends on state in a database is more complex than one that
tests units in isolation.

None of these points are arguing against Factory Girl, which is a great tool
for doing what it does; they are arguing against integrating with the database
in "unit" tests.

------
darrencauthon
As a guy who recently switched from years of ASP.Net MVC to Rails, I read this
post and wanted to shout...

"Watch out everybody, he's hitting the database!!!"

Ruby is a great language that I love, but this is one of those cases where
Ruby's conciseness and readability hide a TON of complexity. And complexity in
tests is death.

I've seen it for myself -- there's a lot of technical debt interest in those
tests. It looks manageable at the beginning, especially within the scope of a
blog post, but when the app grows and grows and grows, the tests fail.

------
amurmann
To get the best form both fixtures and factories, I can strongly recommend
<http://github.com/rdy/fixture_builder> It utilizes factories to build up your
fixtures. This way you only need to specify what you actually care about in
you r fixture which preserves readability. But you still get the speed of
fixtures. The one downside is that you can never assume a complete knowledge
of what's in your DB. This might break test for scopes for example.

However I more and more agree with the general notion that your unit test
should not hit the DB. However, Rails works against that. Avdi Grimm's
"Object's on Rails" (<http://objectsonrails.com/>) has some interesting
suggestions on how to get some good test isolation out of Rails.

------
rob-anderson
Factory Girl has saved me countless hours - I love it.

You can use build instead of create to avoid the db, as per previous comments.
You don't have to use it at all if writing a simple unit test.

But for teeing up complex scenarios prior to a fat integration test, it rocks.

------
s_kilk
I'm coming to the later stages of implementing an MVP with Rails and for me,
FactoryGirl and RSpec have been a godsend.

------
calgaryeng
Old news!

------
ThePherocity
Yea, once your model gets more complex than a dozen or so objects, then
something like this is awesome. I only with there was an equivalent in ASP.Net
MVC which is the current bill payer. (Plant is the closest I've seen, but not
quite as elegant, and I'm a little concerned over support).

~~~
edandersen
How is this different to mocking frameworks like RhinoMocks or the new
Microsoft.Fakes?

~~~
ThePherocity
You're creating an actual instance of that object preloaded with whatever you
need rather than a mock of that item which implements a fake implementation.
They're not really competing since Mocks are most useful when mocking an
interface, and Factory Girl is best at creating a number of usable objects.

------
briandear
Factory Girl is good but Fabrication is far better.

