From: Pat Maddox Date: 2006-05-16T08:33:15+09:00 Subject: Re: BDD and mocking objects I've been doing lots of reading this afternoon, and came across a few comments that leave me with more questions. Dave Astels said in a podcast that RSpec doesn't take the place of functional or integration tests. Martin Fowler wrote that you must use coarse grained acceptance tests. I simply don't know what functional, integration, and acceptance tests are, and how they differ from unit tests. Where can I find some info on why I should use them, and how to use them effectively? Pat On 5/15/06, Jake McArthur wrote: > 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 > >> > > >> > >> > >> > > > > >