First off, I don't like my original response about mocking IList<> and
expecting a call to add.  It exposes too much about the implementation
of your class.  If the code is changed to use AddRange() on the
IList<> instead of Add(), the unit test will fail (since Add isn't
called), but the results are still valid.

I think a better approach for testing the SearchForArticles method
would be to stub the DAO's to return the specific items and then,
after calling SearchForArticles, make sure the criteria.ServiceAreas
contain the objects your stubs returned.  This tests the behavior of
the method and not the implementation.

As for your other question, I would do something similar: stub
System1.Search and System2.Search to returned pre-determined results
and, after the method call, make sure Result.SystemResults contains
the items the stubbed search objects returned.  I assume your
SearchAgainstSeveralSystems is supposed to return the Result object?

Something like this:

var result1 = new System1Result();
var result2 = new System2Result();
var system1 = MockRepository.Stub<System1>();
system1.Stub(s => s.Search("abc")).Returns(result1);
var system2 = MockRepository.Srub<System2>();
system2.Stub(s => s.Search("abc").Returns(result2);

var sut = new Searcher();
var result = sut.SearchAgainstServeralSystems("abc");

Now make sure result.SystemResults contains both result1 and result2.

-- 
Patrick Steele
http://weblogs.asp.net/psteele



On Wed, Nov 18, 2009 at 11:45 AM, Goatified Creature
<[email protected]> wrote:
> Yep that worked ok.
>
>
> Now, to change the subject very slightly, now I am understanding the
> one assert per test strategy, what tests would be recommended for
> testing the following pseaudo method:
>
> public Result SearchAgainstSeveralSystems (string SearchTerm)
> {
>     System1Result = System1.Search(SearchTerm);
>     System2Result = System2.Search(SearchTerm);
>
>     Result result = new Result;
>     Result.SystemResults.Add(System1Result);
>     Result.SystemResults.Add(System2Result);
> }
>
>
> my understanding would be make sure you hit the various systems:
> search_that_system1_is_searched_against (mocking system1, and stubbing
> system2 and result.SystemResults.Add
> search_that_system2_is_searched_against (mocking system2, and stubbing
> system1 and result.SystemResults.Add
>
>
> then, maybe 2 searches for
> search_that_results_get_added_to_results (stubbing both systems and
> mocking the result.SystemResults.Add method expecting two invocations)
>
> Then, should there be a test that asserts the returned result is the
> result object? Suppose not as its just a return command but I could
> always mistakenly return another Result object.
>
> Alternatively, instead of mocking the result.SystemResults.Add method,
> I could simply do a couple of tests that Assert(result.SystemResults
> [0], Is.SameAs (a dummy object returned from stubbed systems).
>
> Does this make sense? Problem is that the test doesn't have a handle
> to the Result object and therefore, can't have a direct assert against
> it.
>
> Cheers
>
>
> On Nov 18, 3:43 pm, Patrick Steele <[email protected]> wrote:
>> If ArticleSearchCriteria has virtual members, I think you could mock
>> the ServiceAreas collection and set an expectation on the "Add"
>> method.  Assuming you have something like this:
>>
>> class ArticleSearchCriteria
>> {
>>     public virtual IList<ServiceArea> ServiceAreas { get; set; }
>>
>> }
>>
>> You could create a mock IList<ServiceArea> and set an expectation on
>> the Add method.  Then stub ArticleSearchCritera.ServiceAreas property
>> to return your mocked IList<ServiceArea> (below is AAA syntax and
>> typed on-the-fly):
>>
>> var saList = MockRepository.GenerateMock<IList<ServiceArea>>();
>> var searchCriteria = MockRepository.GenerateStub<ArticleSearchCriteria>();
>> s.ServiceAreas = saList; // I think you can just do the assign with AAA 
>> syntax
>>
>> Now tell Rhino mocks you expect an Add of your resultFromDAO:
>>
>> saList.Expect(c => c.Add(resultFromDAO));
>>
>> I think that'll get you going.
>>
>> ---
>> Patrick Steelehttp://weblogs.asp.net/psteele
>>
>> On Wed, Nov 18, 2009 at 9:50 AM, Goatified Creature
>>
>> <[email protected]> wrote:
>> > Exactly! I want!!! However, i was struggling to find an appropriate
>> > Contraint to meet this. I am now looking at the AAA syntax and
>> > attempting to follow the test one thing per test strategy, but it's
>> > difficult when you pick up bad habits!!!
>>
>> > On Nov 18, 12:39 pm, Patrick Steele <[email protected]> wrote:
>> >> Let me see if I understand exactly what you want (ironically, I
>> >> learned RhinoMocks with the AAA syntax and I find it hard sometimes to
>> >> follow the record/play syntax).  The SearchManager class you're
>> >> testing has the following members:
>>
>> >> ISearchDAO SearchDAO { get; set; }
>> >> IServiceAreaDAO ServiceAreaDAO { get; set; }
>> >> ArticleSearchResult SearchForArticles(ArticleSearchCriteria criteria,
>> >> int[] serviceAreaIds)
>>
>> >> You want to ensure that the when calling SearchForArticles, the
>> >> results of any calls made to ServiceAreaDAO.GetById(int) are added to
>> >> the criteria.ServiceAreas collection?
>>
>> >> --
>> >> Patrick Steelehttp://weblogs.asp.net/psteele
>>
>> >> On Mon, Nov 16, 2009 at 9:52 AM, Goatified Creature
>>
>> >> <[email protected]> wrote:
>>
>> >> > Hi, I have been trying to write a unit test in C# for a Manager
>> >> > method. I am mocking two DAOS. However, the parameter passed to the
>> >> > manager method will be further populated by the manager and passed as
>> >> > an argument to one DAO. I wish to place a constraint on the DAO call
>> >> > to ensure this property was populated correctly. Maybe this is easier
>> >> > to demonstrate through code....
>>
>> >> > // the manager to test
>> >> >            SearchManager managerToTest = new SearchManager();
>>
>> >> >            // mock the two DAOs
>> >> >            MockRepository mocks = new MockRepository();
>> >> >            ISearchDAO mockedSearchDAO = mocks.StrictMock<ISearchDAO>
>> >> > ();
>> >> >            IServiceAreaDAO mockedServiceAreaDAO =
>> >> > mocks.StrictMock<IServiceAreaDAO>();
>>
>> >> >            // create a search criteria object that does not have it's
>> >> > ServiceAreas collection populated
>> >> >            ArticleSearchCriteria criteria = new ArticleSearchCriteria
>> >> > ();
>>
>> >> >            // now the manager method will populate the ServiceAreas
>> >> > property of criteria with a collection of
>> >> >            // matching ServiceArea objects matching the below int
>> >> > array
>> >> >            int[] serviceAreaIds = { 345435 };
>> >> >            ServiceArea serviceArea = new ServiceArea();
>>
>> >> >            // and these will be the pretend results
>> >> >            ArticleSearchResult resultFromDAO = new ArticleSearchResult
>> >> > ();
>>
>> >> >            using (mocks.Record())
>> >> >            {
>> >> >                Expect.Call(mockedServiceAreaDAO.GetById
>> >> > (345435)).Return(serviceArea);
>>
>> >> >                // Now, here, I want a contraint to say
>> >> >                // ensure criteria.ServiceAreas contains the above
>> >> > serviceArea object. This will be
>> >> >                // set before calling the below DAO method.
>> >> >                Expect.Call(mockedSearchDAO.SearchForArticles
>> >> > (criteria)).Return(resultFromDAO);
>>
>> >> >            }
>> >> >            using (mocks.Playback())
>> >> >            {
>> >> >                // inject DAO dependencies
>> >> >                managerToTest.SearchDAO = mockedSearchDAO;
>> >> >                managerToTest.ServiceAreaDAO = mockedServiceAreaDAO;
>>
>> >> >                // call the method ensuring correct results. This
>> >> > works fine
>> >> >                Assert.That(managerToTest.SearchForArticles(criteria,
>> >> > serviceAreaIds), Is.SameAs(resultFromDAO));
>>
>> >> >                // Now, I shouldn't be validating the ServiceAreas
>> >> > collection was populated through the assert methodology
>> >> >                Assert.That(criteria.ServiceAreas, Has.Member
>> >> > (serviceArea));
>> >> >            }
>>
>> >> > I have been tearing my receding hair out all afternoon through the
>> >> > Rhino Mocks documentation to understand how to test this scenario.
>>
>> >> > Cheers!!!

--

You received this message because you are subscribed to the Google Groups 
"Rhino.Mocks" group.
To post to this group, send email to [email protected].
For more options, visit this group at 
http://groups.google.com/group/rhinomocks?hl=.


Reply via email to