Hacker News new | ask | show | jobs
by davidcuddeback 5048 days ago
I would argue that those aren't unit tests, because they depend on the collaborators that you're passing into the unit under test. A change to those objects could break your unit test. That makes it an integration test.

If you're using your unit tests to inform your design, then the complexity in the extraneous objects is relevant, because they tell you how coupled your unit under test is to its dependencies. This is what FactoryGirl hides from you.

I tend to use fake objects for the collaborators. Usually just a vanilla test double will do, but sometimes I use RSpec's stub_model if the collaborator has to behave more "model-like".

I'd recommend http://pyvideo.org/video/631/fast-test-slow-test and http://www.confreaks.com/videos/641-gogaruco2011-fast-rails-... if you haven't seen them already.

2 comments

And I would argue that arguing bout what a unit test is and isn't has missed the topic of this parent post entirely. I have seen those links and I know both people as they worked where I work now. Arguing over speed and/or what a pure unit test is has never been my cup of tea because every single codebase is different for a variety of reasons.

Tests and code don't always fall into these neat cult buckets we've drawn up for ourselves. Good doesn't mean just fast. It can also mean readable, to wit FG usage addresses quite nicely. Just another tool in the toolbox.

Just like ruby, I can write crap tests with or without FG and great tests with or without FG. Same goes for stubs, doubles, and collaborators.

> And I would argue that arguing bout what a unit test is and isn't has missed the topic of this parent post entirely.

You do raise a valid point: we're arguing about a definition. I don't think that misses the point though, because this thread is specifically discussing the use of FactoryGirl in unit tests. Where I disagree with you is on the importance of definitions. I think it's important to understand the definition of a unit test vs an integration test vs a system test, because without agreeing on those definitions, we don't stand a chance of having a reasonable discussion. If we have different definitions for a word, then our arguments will be talking past each other.

> Tests and code don't always fall into these neat cult buckets we've drawn up for ourselves.

(I'll ignore the loaded language, because that's not conducive to rational discussion.) From this point on, you use the word "tests" instead of "unit tests," and your points are valid because you're talking about the broader category of tests. I'm not. I'm specifically discussing unit tests, which has been the topic of discussion for this entire thread, going all the way up to the top-level comment by indrekju.

> because every single codebase is different for a variety of reasons

I agree with you here. Every codebase is different, and so are their testing requirements. For small gems, I tend to write all integration tests with few unit tests. For larger Rails projects, I write mostly unit tests with some integration tests to catch the cases where an interface changed but I forgot to update a fake object. If you're saying that different codebases differ in their relative requirements of different types of tests (unit vs integration, etc), then I agree. In fact, I would take that a step further, and say the testing requirements also depend on the team. But if you're arguing that the definition of a unit test changes depending on the codebase's testing requirements, then I can't agree.

I'm not refuting the usefulness of FactoryGirl in integration, system, or acceptance tests. Just unit tests.

Having definitions for jargon gives us tools to learn and discuss things at a more abstract level. That doesn't necessitate applying those ideas dogmatically. If anything, I think it helps you understand the trade-offs so that you can be pragmatic, because pragmatism depends on understanding.

There's a saying in nursing: "If it's wet, dry it. It it's dry, wet it."

I think we need the same thing in programming.

If it's slow, make it faster. If it's unreadable, make it readable. If it's coupled, decouple it.

Then just stop worrying if we fall into official definitions of unit, integration, collaborator, mock, stub, double, etc. I swear we spend more time as an industry arguing about that stuff than actually writing code, myself included.