On Dec 26, 2007 3:23 PM, Pat Maddox <[EMAIL PROTECTED]> wrote: > On Dec 23, 2007 2:27 PM, Zach Dennis <[EMAIL PROTECTED]> wrote: > > I know the questioned are directed towards Dan so I hope you don't me > > chiming in. My comments are inline. > > Thanks a lot for your comments, I really appreciate them. I've been > dying to respond to this for the past several days, but haven't had > internet access. > > > > On Dec 15, 2007 2:17 AM, Pat Maddox <[EMAIL PROTECTED]> wrote: > > > > > > On Dec 8, 2007 4:06 AM, Dan North <[EMAIL PROTECTED]> wrote: > > > > I prefer the mantra "mock roles, not objects", in other words, mock > > > > things > > > > that have behaviour (services, components, resources, whatever your > > > > preferred term is) rather than stubbing out domain objects themselves. > > > > If > > > > you have to mock domain objects it's usually a smell that your domain > > > > implementation is too tightly coupled to some infrastructure. > > > > > > Assuming you could easily write Rails specs using the real domain > > > objects, but not hit the database, would you "never" mock domain > > > objects (where "never" means you deviate only in extraordinary > > > circumstances)? I'm mostly curious in the interaction between > > > controller and model...if you use real models, then changes to the > > > model code could very well lead to failing controller specs, even > > > though the controller's logic is still correct. > > > > In Java you don't mock domain objects because you want to program > > toward an interface rather then a single concrete implementation. > > Conceptually this still applies in Ruby, but because of differences > > between the languages it isn't a 1 to 1 mapping in practice. > > I must be misunderstanding you here, because you say you "don't mock > domain objects," and the rest of your email suggests that you mock > basically everything. > > <snip> > > > > Do you try to test each > > > class in complete isolation, mocking its collaborators? > > > > Yes. The pattern I find I follow in testing is that objects whose job > > it is to coordinate or manage other objects (like controllers, > > presenters, managers, etc) are always tested in isolation. > > Interaction-based testing is the key here. These objects can be > > considered branch objects. They connect to other branches or to leaf > > node objects. > > > > Leaf node objects are the end of the line and they do the actual work. > > Here is where I use state based testing. I consider ActiveRecord > > models leaf nodes. > > What about interactions between ActiveRecord objects. If a User > has_many Subscriptions, do you mock out those interactions?
For me it depends. If I am testing my User object and it has a custom method called find_subscriptions_which_have_not_expired_but_which _has_not_been_read_in_over_n_days. I will not mock out any interactions with the subscriptions at that point. This is for two reasons. One, when I first get this to work I may do it in pure ruby code (no SQL help) just to get it working. At some later date/time this is going to move to SQL. I want my test to not have to change in order to do this. If I was interaction-based testing this custom find method then it wouldn't really help me ensure I didn't break something. Secondly, I view my model has a leaf node object. Most of everything my model does I want to state based test the thing to ensure the results are what I want (and not the interactions). Some times I find there is a method where I will mock an association because I truly don't care about the result, and I really only care about the interaction. For example if User delegates something to the Subscription class either via a delegate declaration or a simple method which delegates. For example: delegate :zip_code, :to => :address OR def zip_code address.zip_code end > Would you > still mock them out if User and Subscription were PROs (plain Ruby > objects) and persistence were handled separately? Possibly. I think it depends on how the objects used each other, what kind of mini-frameworks or modules were in place to give functionality, etc. Since models get most of their functionality through inheritance of ActiveRecord::Base it would be difficult to compare w/o knowing how my PROs were hooked up. Composition or inheritance makes a difference in my head right now. Do you have any specific concrete examples in mind? > > > > > When you use > > > interaction-based tests, do you always leave those in place, or do you > > > substitute real objects as you implement them (and if so, do your > > > changes move to a more state-based style)? > > > > Leave the mocked out collaborators in place. An interaction based test > > verifies that the correct interaction takes place. As soon as you > > remove the mock and substitute it with a real object your test has > > become compromised. It's no longer verifying the correct interaction > > occurs, it now only makes sure your test doesn't die with a real > > object. > > This leads to perhaps a more subtle case of my previous > question...ActiveRecord relies pretty heavily on the real classes of > objects. To me, this means that it would make more sense to use mocks > if you didn't use AR, but use the real objects when you are using AR. > Again, this is only between model objects. I agree that controller > specs should mock them all out. I agree with this. This is largely how I work now as described above. > > > > > I realize that's a ton of questions...I'd be very grateful (and > > > impressed!) if you took the time to answer any of them. Also I'd love > > > to hear input from other people as well. > > > > > > > It's too bad we can't just stand at a whiteboard and talk this out. > > The answers to these questions could fill a book and email hardly does > > it justice to provide clear, coherent and complete answers. Not that > > my response are "answers" to your questions, but it's how I think > > about testing and TDD. > > Thanks again for your thoughtful reply. Looking forward to hearing a > little bit more. > ditto, -- Zach Dennis http://www.continuousthinking.com _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users