On 2/22/07, <b class="gmail_sendername">Pat Maddox</b> <<a href="mailto:pergesu@gmail.com">pergesu@gmail.com</a>> wrote:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>specify "should find all users over the given age" do<br> User.should_receive(:find).with(:all, :conditions => ["age > ?", 18])<br> User.find_older_than 18<br>end</blockquote><div><br>I don't have a good suggestion here, but an observation is that the spec is too fine-grained and brittle, which, as you mention below, inhibits refactoring and TDD flow, etc.
<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">I don't know about you, but to me that sucks. There is no TDD rhythm<br>there. We write a failing spec, but it's a fairly complex spec. On
<br>top of that we've basically implemented the method from within the<br>spec. That's not TDD.<br><br>We also can't refactor. Let's say that at some point we decided to<br>change the method to<br><br>def
User.find_older_than(age)<br> find(:all).select {|u| u.age > age }<br>end<br><br>Our spec would break, even though the semantics of<br>User.find_older_than hasn't changed.</blockquote><div> </div>I have experienced similar troubles as you have in the past, and the usage of mock-based testing in these scenarios still hasn't fully clicked for me either. I know something's not right, but I can't put my finger on what it is. I suspect it's that the APIs you're working with are too data-intensive and not message-intensive (
i.e., "tell don't ask"), which is where mock testing really shines. I'll defer to this post from Steve Freeman (there are probably other entries too that are similar), and the quote that apparently originates from Joe Walnes, "Don't mock types you don't own".
<br><br><a href="http://stevef.truemesh.com/archives/000194.html">http://stevef.truemesh.com/archives/000194.html</a><br><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I'm beginning to think that most of the time, you don't want to use a<br>test DB at all. When you're testing an AR model, just use an<br>in-memory record and stub any associations you need. But when you do<br>
do something that interacts with the database - like doing a custom<br>find - you need to use the database to make sure that you're getting<br>the right results. Whether you use fixtures or create some records in<br>
the setup method, you have to actually hit the db.</blockquote><div><br>I don't have a better answer, so maybe your instinct is right here -- don't fight with brittle mocks, if the database works for you and doesn't slow you down too much.
<br><br>I would think Dave, David and Aslak would have good input on this topic, and hope they have a moment to share their experiences.<br></div><br>Cheers,<br>/Nick<br></div>