<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Aaron Feng: Another reason for Rhino Mocks Generic Constraint</title>
    <link>http://www.aaronfeng.com/articles/2007/10/08/another-reason-for-rhino-mocks-generic-constraint</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Adventures in software development</description>
    <item>
      <title>Another reason for Rhino Mocks Generic Constraint</title>
      <description>&lt;p&gt;&lt;a href="http://codebetter.com/blogs/jeffrey.palermo/default.aspx"&gt;Jeffrey Palermo&lt;/a&gt; recently had a post about &lt;a href="http://codebetter.com/blogs/jeffrey.palermo/archive/2007/10/02/169065.aspx"&gt;Generic Constraints for Rhino Mocks - make unit tests more readable&lt;/a&gt;.  I would like to touch on an alternative reason why you might want to use Generic Constraint.  I'll reiterate Jeffrey's example before I start, with minor modification, and offer possible alternative ways the tests can be written.&lt;/p&gt;

&lt;p&gt;Jeffrey implemented a GenericConstraint class to capture the parameter of the method call on a mock object.  Below resembles his original example:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;[Test]
public void ShouldSaveObjectWithAllInformation() {
    string firstName = &amp;quot;Aaron&amp;quot;;
    string lastName = &amp;quot;Feng&amp;quot;;

    MockRepository mocks = new MockRepository();
    IPersonRepository personRepository = mocks.CreateMock&amp;lt;IPersonRepository&amp;gt;();

    personRepository.SavePerson(null);
    GenericConstraint&amp;lt;Person&amp;gt; personConstraint = new GenericConstraint&amp;lt;Person&amp;gt;();
    LastCall.On(personRepository).Constraints(personConstraint);

    mocks.ReplayAll();

    PersonController controller = new PersonController(personRepository);
    controller.PersonFirstName = &amp;quot;Aaron&amp;quot;;
    controller.PersonLastName = &amp;quot;Feng&amp;quot;;
    controller.Save();

    mocks.VerifyAll();

    Person person = personConstraint.GetParameterObject();
    Assert.AreEqual(person.FirstName, firstName);
    Assert.AreEqual(person.LastName, lastName);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once the PersonConstraint captured the Person that is being saved, he asserted that the values are as expected.  This makes the test look more like a typical unit test.&lt;/p&gt;

&lt;p&gt;Jeffrey's goal was to avoid the following code:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public delegate void Proc&amp;lt;P&amp;gt;(P p);

[Test]
public void ShouldSaveObjectWithAllInformationUsingBuildInConstraint() {
    string firstName = &amp;quot;Aaron&amp;quot;;
    string lastName = &amp;quot;Feng&amp;quot;;

    MockRepository mocks = new MockRepository();
    IPersonRepository personRepository = mocks.CreateMock&amp;lt;IPersonRepository&amp;gt;();

    personRepository.SavePerson(null);
    LastCall.On(personRepository).IgnoreArguments().Do(
        new Proc&amp;lt;Person&amp;gt;(delegate(Person person) {
            Assert.AreEqual(person.FirstName, firstName);
            Assert.AreEqual(person.LastName, lastName);
        })
    );

    mocks.ReplayAll();

    PersonController controller = new PersonController(personRepository);
    controller.PersonFirstName = &amp;quot;Aaron&amp;quot;;
    controller.PersonLastName = &amp;quot;Feng&amp;quot;;
    controller.Save();

    mocks.VerifyAll();
    // Notice no asserts
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;An astute reader might say: "Hey you don't have to do that, just implement the Equals method on the Person class."  Which would look like the following:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;[Test]
public void ShouldSaveObjectWithAllInformationUsingEquals() {
    MockRepository mocks = new MockRepository();
    IPersonRepository personRepository = mocks.CreateMock&amp;lt;IPersonRepository&amp;gt;();

    // Have to implement Equals on Person
    personRepository.SavePerson(new Person(&amp;quot;Aaron&amp;quot;, &amp;quot;Feng&amp;quot;));

    mocks.ReplayAll();

    PersonController controller = new PersonController(personRepository);
    controller.PersonFirstName = &amp;quot;Aaron&amp;quot;;
    controller.PersonLastName = &amp;quot;Feng&amp;quot;;
    controller.Save();

    mocks.VerifyAll();
    // Notice no asserts again
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The last example by implementing an Equals on the Person object which made the test look too clean.  The asserts are invisible.  On top of that, you have to implement an Equals method on an Object which you might not ever call  the Equals in the real system.  I believe this is the real power behind Jeffrey's Generic constraint approach.  One should avoid writing any code that is not utilized by the real system just to satify the test.&lt;/p&gt;</description>
      <pubDate>Mon, 08 Oct 2007 07:22:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:9931e209-f75d-475f-9e6c-b09f57b5bc25</guid>
      <author>Aaron Feng</author>
      <link>http://www.aaronfeng.com/articles/2007/10/08/another-reason-for-rhino-mocks-generic-constraint</link>
      <category>programming</category>
    </item>
    <item>
      <title>"Another reason for Rhino Mocks Generic Constraint" by Aaron Feng</title>
      <description>&lt;p&gt;The readability comes after understanding the framework used here (RhinoMocks and NUnit).&lt;/p&gt;

&lt;p&gt;Look at the second example, it's even more cryptic, and third it's magical.&lt;/p&gt;

&lt;p&gt;If you are having trouble understanding the example, perhaps I can explain it in a different way.  Just clarify what parts you are confused about in an email.  My contact info can be found on the side bar.&lt;/p&gt;</description>
      <pubDate>Sun, 06 Jan 2008 17:53:09 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:21fa2374-ba77-436b-80e6-9ed3841c2ad0</guid>
      <link>http://www.aaronfeng.com/articles/2007/10/08/another-reason-for-rhino-mocks-generic-constraint#comment-4327</link>
    </item>
    <item>
      <title>"Another reason for Rhino Mocks Generic Constraint" by Bjorn Reppen</title>
      <description>&lt;p&gt;I wonder if it's even possible for developers who are unfamiliar with the framework to actually read and understand the topmost example?  I tried, but gave up after about a minute.  And you dare call this more readable?&lt;/p&gt;

&lt;p&gt;Come on guys, what happened to KISS?&lt;/p&gt;</description>
      <pubDate>Sun, 06 Jan 2008 13:38:59 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:9531e8d6-a687-4c2e-baba-dfa5e78455a4</guid>
      <link>http://www.aaronfeng.com/articles/2007/10/08/another-reason-for-rhino-mocks-generic-constraint#comment-4321</link>
    </item>
  </channel>
</rss>
