Live data from Hacker News

Rails Testing with Factory Girl

hiringthing.com

11–20 of 36 posts

Re: Rails Testing with Factory Girl

#11
post #5

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.

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().

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.

Re: Rails Testing with Factory Girl

#12
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.

Re: Rails Testing with Factory Girl

#13
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.

Re: Rails Testing with Factory Girl

#14
post #11

Earlier quoted context omitted.

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().

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.

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).

Re: Rails Testing with Factory Girl

#15
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.

Re: Rails Testing with Factory Girl

#16
post #11

Earlier quoted context omitted.

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.

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 becom…

So can someone recommend a Ruby (edit: ideally Sinatra/Sequel, not Rails) app one could look at with a more principled test suite? I'm coming from a more traditional OO background and jumping into Ruby. It's good to see I'm not alone in finding this militant pragmatism somewhat off-putting, but I don't want to reinvent the wheel.

Re: Rails Testing with Factory Girl

#17

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).

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

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.

Re: Rails Testing with Factory Girl

#18
post #11

Earlier quoted context omitted.

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.

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 becom…

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/....

Re: Rails Testing with Factory Girl

#19
post #5

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.

One compromise (edit: on the performance problem) would be to use FactoryGirl to generate some type of (yaml?) cache pre-test-run, automatically refreshing only when the model changes.

Re: Rails Testing with Factory Girl

#20
post #5

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.

Yep, I'm trying to dig myself out from this problem now.

The Rails Tutorial (railstutorial.org) uses Factory Girl and integration tests for just about everything, which is a fast enough approach for its toy application, but I've found that when your application gets more complex your test suite takes forever to run, and setting up the tests gets more and more painful (especially when you start dealing with external APIs).

Does anyone have any opinions on the best resource for teaching effective unit testing in Rails? I'd love to speed up my test suite while not losing coverage.

Post reply on HN