I believe that there are best practices that guide us to think about when to use mocks (in this case "doubles") versus integrating against real dependencies (in this case "Factories"). There is a really good book on testing (caveat: it uses Java examples) that describes the purpose of test-driven development, and I think it's very helpful in this discussion on testing in Rails applications. It describes the intention of testing as follows:
... our intention in test-driven development is to use mock objects to bring out relationships between objects.
Freeman, Steve; Pryce, Nat (2009-10-12). Growing Object-Oriented Software, Guided by Tests (Kindle Locations 3878-3879). Pearson Education (USA). Kindle Edition.
If we think about this emphasis on using test-driven development not only to prevent us from introducing regressions, but to help us think about how our code is structured in terms of its interface and relationships to other objects we will naturally use mocks in many cases. I'll describe how this applies to your specific questions below.
First, in terms of whether we use mock objects or real dependencies in model tests - if we're testing class Foo and its dependency on Bar, we may want to substitute a mock for Bar. In this way we will see clearly the level of coupling to Bar as we'll have to mock the methods that will be called on it. If we find that our mock of Bar is complex, it's a sign that perhaps we should refactor Foo and Bar so that they are less coupled to one another.
In the sense that both Factory.create
and Factory.build_stubbed
have the same effect of keeping you from making dependencies on related classes explicit, I think they're both about as smelly, with Factory.create being the slower of the two options.
In my tests I tend to not worry too much about mocking external dependencies in controllers. I know that this is slower to run than fully mocking, and you don't have the benefit of making the controller coupling to the model explicit, but it's quicker to write the test, and I'm not generally as worried about making clear the relationship between controllers and the persisted records that they manage. As long as you follow patterns of "skinny controllers" there shouldn't be too logic to worry about here anyway. If we need to specify a level of "test smell" here I would say that it's a bit less smelly than model tests that depend on other factories.
I would tend to worry least about Decorators that depend on factories of the classes that they decorate. This is because by definition the decorator should maintain the same interface as the class they decorate. Decoration is most often implemented with some form of inheritance, whether by using method_missing
to delegate to the decoratee, or by explicit subclassing of the decoratee. Because of this you're breaking other rules of good object-oriented programming like Liskov Substitution if the decorator deviates too much from the interface of the thing it decorates. As long as your decoration isn't implemented poorly by breaking rules of good inheritance, the coupling to the class that you decorate is already present, so it's not making things much worse if you have the test of the decoratee depend on a persisted or stubbed factory of the thing that it decorates. You can go crazy with factories in decorator tests and it doesn't matter IMO.
I think that it's important to note that even if you prefer mocks in most cases you should still have some integration tests that use real dependencies. You'll just find that these cover specific high-value cases, where the isolated unit tests provide more coverage of functionality provided by your classes.
At any rate I break all of the above rules sometimes and they are just some guidelines that I use in writing tests. I'm looking forward to hearing how others are using Factories (build_stubbed and really persisted) versus mock objects (doubles) in their tests.
FactoryGirl.build_stubbed
. Probably this explains lack of answers. This or high subjectivity of the term "code smell". – Churchgoer