<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>maonet technotes &#187; Rhino</title>
	<atom:link href="http://maonet.wordpress.com/tag/rhino/feed/" rel="self" type="application/rss+xml" />
	<link>http://maonet.wordpress.com</link>
	<description>IOC(SM):MOC(RM):TDD(NU):SCC(TFS):ORM(L2S):JSL(Jq):CIS(CC)</description>
	<lastBuildDate>Thu, 31 Dec 2009 17:16:53 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='maonet.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/27569a47b055d3d0ff1d52cf3b0ce0d7?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>maonet technotes &#187; Rhino</title>
		<link>http://maonet.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://maonet.wordpress.com/osd.xml" title="maonet technotes" />
		<item>
		<title>Should always ignoreArgument when AssertWasCalled</title>
		<link>http://maonet.wordpress.com/2008/11/28/should-always-ignoreargument-when-assertwascalled/</link>
		<comments>http://maonet.wordpress.com/2008/11/28/should-always-ignoreargument-when-assertwascalled/#comments</comments>
		<pubDate>Fri, 28 Nov 2008 21:30:53 +0000</pubDate>
		<dc:creator>Frank Mao</dc:creator>
				<category><![CDATA[CSLA]]></category>
		<category><![CDATA[MVP]]></category>
		<category><![CDATA[mock]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[Rhino]]></category>

		<guid isPermaLink="false">http://maonet.wordpress.com/?p=326</guid>
		<description><![CDATA[I should have added this option in my test earlier, then I won&#8217;t waste 2+ hours today. The reason causing problem was very simple, AssertWasCalled() method in current verion RhinoMocks (3.5.0.1337 RC) doesn&#8217;t action consistently. I think it&#8217;s because comparing the object reference equalty. I had to add options=&#62;options.IgnoreArguments() to get around from this.
Here is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maonet.wordpress.com&blog=431779&post=326&subd=maonet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I should have added this option in my test earlier, then I won&#8217;t waste 2+ hours today. The reason causing problem was very simple, AssertWasCalled() method in current verion RhinoMocks (3.5.0.1337 RC) doesn&#8217;t action consistently. I think it&#8217;s because comparing the object reference equalty. I had to add options=&gt;options.IgnoreArguments() to get around from this.</p>
<p>Here is a piece of my MVP + CLSA test. Struggled for a while with Property setter, thanks God, it isn&#8217;t that hard.</p>
<pre class="brush: csharp;">

    [TestFixture]
    public class When_initializing_view : EstablishContext
    {
        [Test]
        public void should_call_view_setter_if_id_exists()
        {
            // Arrange
            _mockOrganizationRepository.Expect(x =&gt; x.FindById(1)).Return(_stubOrganizationDTO);

            _mockView = MockRepository.GenerateMock&lt;IEditDetailsView&lt;OrganizationBO&gt;&gt;();

            _presenter = new EditDetailsPresenter&lt;OrganizationBO&gt;(_mockView);

            // Action
            _presenter.InitViewFor(1);

            // Assert
            _mockView.AssertWasCalled(x =&gt; x.CurrentBO = null,
                options =&gt;options.IgnoreArguments() );
        }
    }
</pre>
<p>I then created a generic EditDetailsPresenter, worked as I expected with one concern left: How to mock DataPortal directly. Currently I am still mocking repository. Ideally I should mock DataPortal instead, otherwise I have to make sure there is at least one BO is fully functional.</p>
<p>Mocking DataPortal is very hard, because those Fecth, Create, Update and Delete are all static methods, I had to create an adapter to wrap those static methods, then using StructreMap again inside adapter enable switching between DataPortal and mock DomainDAO, here is what I have tried:</p>
<ol>
<li>Create DomainDAO and IDomainDAO,
<pre class="brush: csharp;">
public class DomainDAO&lt;BO&gt; : IDomainDAO&lt;BO&gt;
{
public BO Fetch(object criteria)
{
return DataPortal.Fetch&lt;BO&gt;(criteria);
}

public BO Create()
{
return DataPortal.Create&lt;BO&gt;();
}

public BO Update(BO bo)
{
return DataPortal.Update&lt;BO&gt;(bo);
}

public void Delete(object criteria)
{
DataPortal.Delete&lt;BO&gt;(criteria);
}
}

public interface IDomainDAO&lt;T&gt;
{
T Fetch(object criteria);
T Create();
T Update(T bo);
void Delete(object criteria);
}
</pre>
</li>
<li>Create DAOManager to Get DomainDAO:
<pre class="brush: csharp;">
public static class DAOManager
{
public static IDomainDAO&lt;BO&gt; DomainDAO&lt;BO&gt;()
{
return ObjectFactory.GetInstance&lt;IDomainDAO&lt;BO&gt;&gt;();
}
}
</pre>
</li>
<li>Change classic factory method in BO from DataPortal to this new DAOManager.
<pre class="brush: csharp;">
public static OrganizationBO GetOrganizationBO(int stakeholderId)
{
return DAOManager.DomainDAO&lt;OrganizationBO&gt;().Fetch(new SingleCriteria&lt;OrganizationBO, int&gt;(stakeholderId));
//            return DataPortal.Fetch&lt;OrganizationBO&gt;(new SingleCriteria&lt;OrganizationBO, int&gt;(stakeholderId));
}
</pre>
</li>
<li>The presenter testing code can be changed to:
<pre class="brush: csharp;">

[SetUp]
public void SetUp()
{
_mockService = MockRepository.GenerateMock&lt;IDomainDAO&lt;OrganizationBO&gt;&gt;();
ObjectFactory.Inject&lt;IDomainDAO&lt;OrganizationBO&gt;&gt;(_mockService);
}

[TearDown]
public void TearDown()
{
ObjectFactory.ResetDefaults();
}

[TestFixture]
public class When_initializing_view : EstablishContext
{
        [Test]
        public void should_call_view_setter_if_id_exists()
        {
            // Arrange
            // We don't need to set return value here.
            _mockService.Expect(x =&gt; x.Fetch(new SingleCriteria&lt;OrganizationBO, int&gt;(68190)));

            _mockView = MockRepository.GenerateMock&lt;IEditDetailsView&lt;OrganizationBO&gt;&gt;();

            _presenter = new EditDetailsPresenter&lt;OrganizationBO&gt;(_mockView);

            // Action
            _presenter.InitViewFor(68190);

            // Assert
            _mockView.AssertWasCalled(x =&gt; x.CurrentBO = null,
                options =&gt; options.IgnoreArguments() );
        }

        [Test]
        public void should_set_error_msg_in_view_if_id_not_exists()
        {
            // Arrange
            Exception ex = new Exception(&quot;Data Not Found&quot;, new DataNotFoundException());
            _mockService.Expect(x =&gt; x.Fetch(new SingleCriteria&lt;OrganizationBO, int&gt;(1)))
                .IgnoreArguments()
                .Throw(new DataPortalException(&quot;DataPortal.Fetch failed.&quot;,
                    ex,
                    null)); // See, we don't have to mock BO here, unless you try to read BO through exception in UI.

            _mockView = MockRepository.GenerateMock&lt;IEditDetailsView&lt;OrganizationBO&gt;&gt;();

            _presenter = new EditDetailsPresenter&lt;OrganizationBO&gt;(_mockView);

            // Action
            _presenter.InitViewFor(1);

            // Assert
            _mockView.AssertWasCalled(x =&gt; x.ShowError(null),
                options =&gt; options.IgnoreArguments() );
        }
</pre>
</li>
</ol>
<p>Fetch can be done this way, but I can&#8217;t mock Save() because it&#8217;s deep in Csla, unless I can override BusinessBase.Save() which is another mission impossible (too many internal classes involved). To make Csla TDD friendly, let ask for TypeMock to save us out.</p>
<pre class="brush: csharp;">
 [TestFixture]
    public class When_view_firing_save_event : EstablishContext
    {
        [Test]
        public void should_set_success_msg_and_set_new_BO_in_view_if_save_new_bo_succeed()
        {
            // Arrange
            OrganizationBO orgBo = DataPortal.Create&lt;OrganizationBO&gt;();
            orgBo.Name = &quot;test Org&quot;;
            Assert.That(orgBo.IsValid, orgBo.GetValidationMessage());

            _mockView = MockRepository.GenerateMock&lt;IEditDetailsView&lt;OrganizationBO&gt;&gt;();
            _mockView.Stub(x =&gt; x.CurrentBO).Return(orgBo).Repeat.Any();

            _presenter = new EditDetailsPresenter&lt;OrganizationBO&gt;(_mockView);

            // This won't work, because BusinessBase.Save() is tightly coupled to DataPortal.
            //_mockService.Expect(x =&gt; x.Update(orgBo)).IgnoreArguments();

            // Use TypeMock to mock DataPortal.Update() inside BusinessBase.Save()
            using (RecordExpectations recorder = RecorderManager.StartRecording())
            {
                  // CAUTION: ALL calls here are mocked!!!
                  recorder.DefaultBehavior.IgnoreArguments();
                  recorder.ExpectAndReturn(DataPortal.Update(orgBo), orgBo);
            }

            // Action
            _mockView.Raise(x =&gt; x.RequestSave += null, this, EventArgs.Empty);

            // Assert
            _mockView.AssertWasCalled(x =&gt; x.CurrentBO = null,
                                      options =&gt; options.IgnoreArguments());

            _mockView.AssertWasCalled(x =&gt; x.ShowMessage(null),
                                      options =&gt; options.IgnoreArguments());

    }
</pre>
<p>We can remove DomainDAO then if using TypeMock to mock DataPortal.</p>
<p>The <a href="http://www.lhotka.net/weblog/CSLANETObjectFactoryAttribute.aspx">new ObjectFactory in CSLA 3.6</a> seems can make this mock easier, looks like your own ObjectFactory is not static class anymore, different than DataPortal. By creating your own IDataPortal or IObjectFactory, <a href="http://code.google.com/p/cslaptrackerfactory/source/browse/trunk/ProjectTrackerHybrid.Core/Framework/Factories/IBusinessBaseServerFactory.cs">as Ryan did</a>,  mocking those service layer objects should become possible. Someday I will look into this CSLA.ObjectFactory thing if we aren&#8217;t going to TypeMock. Rocky&#8217;s statement indicates this will be a lot of work:</p>
<blockquote><p>It is <em>very important</em> to realize that when using this factory model, the data portal does virtually nothing for you. It doesn&#8217;t automatically call MarkOld(), MarkNew() or MarkAsChild(). You assume <em>total responsibility</em> for creating and initializing the business object graph, and for setting the state of all objects in the graph.</p></blockquote>
<p>But it seems <a href="http://cslaptrackerfactory.googlecode.com/">Ryan&#8217;s ObjectFactroy sample code</a> already finished most of them. One thing doesn&#8217;t fit our situation is, we need IRepository&lt;&gt; changed to IDomainObjectRepository in Factory.</p>
<pre class="brush: csharp;">

        private readonly IRepository&lt;T&gt; _repository;
        public BusinessBaseServerFactory(IRepository&lt;T&gt; repository)
        {
            _repository = repository;
        }
</pre>
<p>So far, I think unless CSLA.ObjectFactory can provide an optional attribute something like &#8220;RepositoryType&#8221;, I have to create One ObjectFacotry per BO. Our libaray will become more messier.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/maonet.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/maonet.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/maonet.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/maonet.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/maonet.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/maonet.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/maonet.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/maonet.wordpress.com/326/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/maonet.wordpress.com/326/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/maonet.wordpress.com/326/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=maonet.wordpress.com&blog=431779&post=326&subd=maonet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://maonet.wordpress.com/2008/11/28/should-always-ignoreargument-when-assertwascalled/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/d41c3a25ca01f1e979e2bc86b8c4ed38?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FMao</media:title>
		</media:content>
	</item>
	</channel>
</rss>