From: Jake McArthur Date: 2006-05-16T08:18:04+09:00 Subject: Re: BDD and mocking objects Yes, I would say that is a good guideline in general. For the record, I am not a BDD guru by any means, though I have been using BDD techniques for some time now when using TDD. I have been using RSpec for roughly a month now, I think. - Jake McArthur On May 15, 2006, at 5:42 PM, Pat Maddox wrote: > 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 >> > >> >> >> >