From: Pat Maddox Date: 2006-05-16T07:42:33+09:00 Subject: Re: BDD and mocking objects Thanks for the reply Jake. Very good points, and in fact they basically opened my eyes to a problem that I run into when doing TDD. If I were to write this system from scratch, focusing on behavior, my process would go something like this: 1. Decide to write the Rental class 2. Realize that Rental depends on Movie 3. Write the Movie class 4. Write the Rental class Again, this is a trivial example, so perhaps the problem here is non-obvious (to others, I have a feeling you can see it immediately). At this point I don't care about a Movie, I only care about a Rental and its behavior. The way I've done things though requires me to write the Movie class before I even begin working on the Rental's behavior. First of all that sidetracks me for a bit while I write Movie and its tests, and in general I think it leads to me writing more tightly coupled code. It seems obvious to me now that when writing a unit test, I should mock out any relationships, so basically any object that's not the one I'm explicitly testing. I'm sure there are exceptions, but does that seem like a good guideline to follow? Pat On 5/15/06, Jake McArthur wrote: > I say it _does_ matter. Behavior driven development, in particular, > emphasizes testing the way that objects interact. As such, it should > be tested that the Rental class is treating the Movie class properly. > Think of it this way. What if you decided there should be another > type of object that has a similar interface to a Movie object? You > don't want your Rental tests to be locked to the Movie class since > you want to be able to pass in the other kind of object as well. The > only way to test that is with mock objects. Other reasons for mocking > could include an incomplete or buggy implementation of the Movie > class and better specification of what the roles and responsibilities > of each object are in the program. > > - Jake McArthur > > On May 15, 2006, at 5:08 PM, Pat Maddox wrote: > > > Brian Hughes discussed BDD [1] in a recent post, which piqued my > > interest enough to check out RSpec. I used his idea and went through > > the first chapter of Refactoring to learn the rspec ropes. > > > > The most interesting stuff is the specs for Customer, but they're kind > > of long, so I'm going to show a less interesting spec. > > > > context "A new rental" do > > setup do > > @movie = Movie.new("New Movie", Movie::REGULAR) > > @rental = Rental.new(@movie, 3) > > end > > > > specify "should have a movie and rental length" do > > @rental.movie.should_be @movie > > @rental.days_rented.should_be 3 > > end > > end > > > > I'm wondering if I should be using a mock instead of creating a new > > Movie object in setup. This is a trivial example and perhaps it would > > be unnecessary, but I want to know if I "get it." I'm testing a > > Rental's behavior, so I really don't care about how a Movie behaves. > > As long as my Rental gets an object that behaves the same way a movie > > does, it should be happy. In this case, I don't care about a Movie's > > title or code, so I could pass in a nil object if I wanted to. Would > > I want to mock the @movie then? Doesn't matter much in this > > particular case, but assume that one of my Rental methods relied on a > > method or two of Movie. > > > > Thanks for any input. > > > > Pat > > > > [1] http://www.ruby-forum.com/topic/65640#77053 > > > > >