<div><span class="gmail_quote">On 04/10/06, <b class="gmail_sendername">David Chelimsky</b> &lt;<a href="mailto:dchelimsky@gmail.com">dchelimsky@gmail.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
There is a saying in the TDD community that you should test YOUR code,<br>not other people's code. There is also another viewpoint that you<br>should test behaviour, not implementation (BDD).</blockquote><div><br>I'm sure both the ideas you mention above have been around for a long time and are not necessarily related to a particular community. To me, the idea of &quot;not testing other people's code&quot; mainly applies in the context of unit testing. I would still want to have higher-level tests that test the system as a whole.
<br><br>To me, the idea of &quot;testing behaviour, not implementation&quot; is the difference between black-box and white-box testing - not the difference between TDD and BDD. I do not use a BDD framework, but my preference would always be to test behaviour, because I think this leads to less brittle, more readable tests where the intent is clear. However, I prefer to be pragmatic rather than religious about avoiding testing the implementation.
<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;">What I would really want to ensure here is that Person validates<br>uniqueness of email, not how it does it. What I would do is something
<br>like:<br><br>def test_person_should_validate_uniqueness_of_email<br>&nbsp;&nbsp;assert_true Person.new(:email =&gt; &quot;<a href="mailto:a@b.com">a@b.com</a>&quot;).save<br>&nbsp;&nbsp;assert_false Person.new(:email =&gt; &quot;<a href="mailto:a@b.com">
a@b.com</a>&quot;).save<br>end<br><br>The primary argument against this approach is that this test requires<br>real interaction w/ the database and unit tests aren't supposed to<br>interact w/ the database. While I usually agree w/ that perspective, I
<br>think that needs to be balanced against the fact that AR is very<br>closely tied to the database. So my approach tends towards testing the<br>behaviour (not the implementation) of model classes in the &quot;unit<br>tests&quot; allowing database interaction, but mocking/stubbing that
<br>behaviour in &quot;functional&quot; and/or &quot;integration&quot; tests.<br><br>I'm curioius to hear other people's perspective on this.</blockquote></div><br>I agree with your assessment that because AR is very closely tied to the database, it's sometimes hard to write tests that don't access the database. However, your suggestion that unit tests should interact with the database, but that functional or integration tests should not, seems very back-to-front to me.
<br><br>In a unit test context, I think it's valid to argue that <span style="font-family: courier new,monospace;">validates_uniqueness_of</span> is third party code and&nbsp; does not need to be tested. So conceptually I think think it would be useful to be able to test simply that 
<span style="font-family: courier new,monospace;">validates_uniqueness_of</span> is called from the Person class definition with the expected parameters. Of course this assumes that <span style="font-family: courier new,monospace;">
validates_uniqueness_of</span> is tested thoroughly in AR tests (or at least it's being used by enough people that we trust it to work!). If the uniqueness of a person's email address is a critical business requirement of the system, I would expect a high-level test to verify that requirement.
<br>-- <br>James.<br><a href="http://blog.floehopper.org">http://blog.floehopper.org</a>