Exactly the same idea! :D

My implementation was coming down functionally exactly the same, only
I didn't make as extension method and didnt use Linq Any, Select and
other methods... which now that I think about it is quite nice :D


Thanks for sharing the code!


Vladan


On Sep 25, 1:48 pm, "Simone Busoli" <[EMAIL PROTECTED]> wrote:
> This is what I've come up with, it was an interesting experiment:
> public static class MockRepositoryExtensions
>     {
>         public static void StubAndReturn<T, V>(this MockRepository mockery,
> T input, V toReturn,
>                                                Expression<Func<T, V>> expr)
>         {
>             var methods = GetMethods(expr).Reverse().ToArray();
>
>             var mocks = new Dictionary<Type, object>{{typeof (T), input}};
>
>             foreach (var method in methods.Take(methods.Count() - 1))
>                 if (!mocks.ContainsKey(method.ReturnType))
>                     mocks.Add(method.ReturnType,
> mockery.Stub(method.ReturnType));
>
>             for (var i = 0; i < methods.Length; i++)
>             {
>                 var methodArguments = methods[i].GetParameters().Select(p =>
> p.DefaultValue);
>
>  SetupResult.For(methods[i].Invoke(mocks[methods[i].DeclaringType],
>                                                   methodArguments.Any() ?
> new object[] {methodArguments} : null)).
>                     IgnoreArguments()
>                     .Return(i < methods.Length - 1 ?
> mocks[methods[i].ReturnType] : toReturn);
>             }
>         }
>
>         private static IEnumerable<MethodInfo> GetMethods<V,
> T>(Expression<Func<T, V>> expr)
>         {
>             var body = expr.Body as MethodCallExpression;
>
>             while (body != null)
>             {
>                 yield return body.Method;
>                 body = Expression.Lambda<Action<IRepository>>(body.Object,
> expr.Parameters).Body as MethodCallExpression;
>             }
>         }
>     }
>
> It allows me do do this:
>
> [TestFixture]
> public class CallChain
> {
>     [Test]
>     public void Test()
>     {
>         var mockery = new MockRepository();
>
>         var repository = mockery.Stub<IRepository>();
>         var toReturn = new ArrayList();
>
>         using (mockery.Record())
>         {
>             mockery.StubAndReturn(repository, toReturn, repo =>
> repo.Find(null)
>
>  .Order(null)
>
>  .Group(null)
>                                                                     .All());
>         }
>         using (mockery.Playback())
>         {
>             var returnedItems = repository.Find(null)
>                 .Order(null)
>                 .Group(null)
>                 .All();
>
>             Assert.That(returnedItems, Is.EqualTo(toReturn));
>         }
>     }
>
> }
> On Thu, Sep 25, 2008 at 1:31 PM, Vladan <[EMAIL PROTECTED]> wrote:
>
> > My idea is to provide a chain and a result to attach at the end of the
> > chain and have lambda inspector go over the chain and connect the dots
> > (mock them).
>
> > Automocking container will not work I think because these are not
> > dependencies, but chaining... although IMO each of them could end in
> > the container and be accessible (additional benefit, but not needed
> > for me at this point).
>
> > My current idea is something like this:
>
> > EntityRepositoryMocker.SetupMock(repo =>
> > repo.Find(byCriteria).Order(byOrder).Group(byGroup).All())
> >                                   .On(customerRepository.Find(byCriteria))
>
> > .Return(someObjectWhichShouldBeOfSameTypeAsTheLastMethodInChainWhichReturnsIt)
>
> > The end object of "AttachTo" is IMethodOptions, so the "Return" part
> > is actually Rhino part which is then flexible enough to add
> > constraints and such further on on the last method in chain.
>
> > Besides this, if everything goes ok, you would also have instead of
> > SetupMock, a SetupExpectation which would work in exact same way
> > except it would do instead of SetupResult.For, an Expect.Call.
>
> > Ill start cracking at it now, keep your fingers crossed that it
> > works :)
>
> > Btw. For the generalise approach... if I have a Lambda Inspector and a
> > Mocker which mocks and chains the result of Inspector, basically the
> > solution is already generalised for any kind of fluent interface
> > mocking.
>
> > Vladan
>
> > On Sep 25, 12:56 pm, "Simone Busoli" <[EMAIL PROTECTED]> wrote:
> > > Good. One question, how do you generalize this approach? I mean, you call
> > > chain involves stuff you need to mock - actually, stub - and a final
> > return
> > > type. I dealt with it leaving the last call out of the loop and handling
> > it
> > > by hand. I'd like to see what you come up with in the end. BTW, seems a
> > good
> > > usage of the auto mocking container.
>
> > > On Thu, Sep 25, 2008 at 12:52 PM, Vladan <[EMAIL PROTECTED]> wrote:
>
> > > > .Invoke ..... aaaaargh, it was right in front of me and I forgot about
> > > > it... thnx so much for the idea! it should work perfectly now.
>
> > > > Ill try it out tonight and let you know.
>
> > > > Vladan
>
> > > > On Sep 23, 4:58 pm, "Simone Busoli" <[EMAIL PROTECTED]> wrote:
> > > > > Here's what I've come up with, I'm not sure what are you trying to do
> > > > > exactly.
> > > > > [TestFixture]
> > > > > public class CallChain
> > > > > {
> > > > >     [Test]
> > > > >     public void Test()
> > > > >     {
> > > > >         var mockery = new MockRepository();
>
> > > > >         var repository = mockery.DynamicMock<IRepository>();
> > > > >         var findMock = mockery.DynamicMock<IFindQueryPart>();
> > > > >         var orderMock = mockery.DynamicMock<IOrderQueryPart>();
> > > > >         var groupMock = mockery.DynamicMock<IGroupQueryPart>();
> > > > >         var returnedItemsStub = new ArrayList();
>
> > > > >         var mocks = new object[] { groupMock, orderMock, findMock,
> > > > > repository };
>
> > > > >         var methods = MethodsFromLambda(repo => repo.Find(null)
> > > > >                                                  .Order(null)
> > > > >                                                  .Group(null)
> > > > >                                                  .All()).ToList();
>
> > > > >         using (mockery.Record())
> > > > >         {
> > > > >             for (var i = methods.Count - 1; i > 0; i--)
> > > > >                 SetupResult.For(methods[i].Invoke(mocks[i], new
> > object[]
> > > > > {null}))
> > > > >                     .IgnoreArguments()
> > > > >                     .Return(mocks[i - 1]);
>
> > > > >             SetupResult.For(methods[0].Invoke(groupMock,
> > > > > null)).IgnoreArguments().Return(returnedItemsStub);
> > > > >         }
> > > > >         using (mockery.Playback())
> > > > >         {
> > > > >             var returnedItems = repository.Find(null)
> > > > >                 .Order(null)
> > > > >                 .Group(null)
> > > > >                 .All();
>
> > > > >             Assert.That(returnedItems,
> > Is.EqualTo(returnedItemsStub));
> > > > >         }
> > > > >     }
>
> > > > >     private static IEnumerable<MethodInfo>
> > > > > MethodsFromLambda(Expression<Action<IRepository>> expr)
> > > > >     {
> > > > >         var body = expr.Body as MethodCallExpression;
>
> > > > >         while (body != null)
> > > > >         {
> > > > >             yield return body.Method;
> > > > >             body =
> > Expression.Lambda<Action<IRepository>>(body.Object,
> > > > > expr.Parameters).Body as MethodCallExpression;
> > > > >         }
> > > > >     }
>
> > > > > }
>
> > > > > public interface IRepository
> > > > > {
> > > > >     IFindQueryPart Find(object o);
>
> > > > > }
>
> > > > > public interface IFindQueryPart
> > > > > {
> > > > >     IOrderQueryPart Order(object order);
>
> > > > > }
>
> > > > > public interface IOrderQueryPart
> > > > > {
> > > > >     IGroupQueryPart Group(object projection_for_group);
>
> > > > > }
>
> > > > > public interface IGroupQueryPart
> > > > > {
> > > > >     ArrayList All();
>
> > > > > }
> > > > > On Tue, Sep 23, 2008 at 9:03 AM, Vladan <[EMAIL PROTECTED]> wrote:
>
> > > > > > no one?
>
> > > > > > On Sep 22, 10:50 am, Vladan <[EMAIL PROTECTED]> wrote:
> > > > > > > Actually sorry, I've expressed something wrong...
>
> > > > > > > from MethodInfo I get the type that needs to be mocked... so I
> > can
> > > > > > > easily create the mock itself:
>
> > > > > > > var mock = mocks.DynamicMock(methodInfo.ReturnType);
>
> > > > > > > ... now how can I assign this?
>
> > > > > > > From methodInfo I have a method to which this mock needs to be
> > > > > > > assigned to (methodInfo.Name), if I could only do this:
>
> > > > > > > SetupResult.For(findMethodInfo).Return(findMethodReturnTypeMock);
>
> > > > > > > On Sep 22, 10:39 am, Vladan <[EMAIL PROTECTED]> wrote:
>
> > > > > > > > I have a bit of a strange situation.
>
> > > > > > > > I have an Repository implementation which is based on a fluent
> > > > > > > > interface for defining a Find query, it looks something like
> > this:
>
> > > > > > > > var returnedItems = repository.Find(some_ICriteria)
> > > > > > > >                                            .Order(some_Order)
>
> > > > > >  .Group(some_Projection_for_group)
> > > > > > > >                                            .All()
>
> > > > > > > > Now, when testing this I need to write for example for
> > SetupResult
> > > > the
> > > > > > > > following tedious code:
>
> > > > > > > > var findMock = mocks.DynamicMock<FindQueryPart>();
> > > > > > > > var orderMock = mocks.DynamicMock<OrderQueryPart>();
> > > > > > > > var groupMock = mocks.DynamicMock<GroupQueryPart>();
> > > > > > > > var returnedItems = new List();
>
> > SetupResult.For(repository.Find(some_ICriteria)).Return(findMock);
> > > > > > > > SetupResult.For(findMock.Order(some_Order)).Return(orderMock);
>
> > SetupResult.For(orderMock.Group(some_Projection_for_group)).Return(groupMock);
> > > > > > > > SetupResult.For(groupMock.All()).Return(returnedItems);
>
> > > > > > > > As you can imagine, for a single query call this is alot of
> > code,
> > > > and
> > > > > > > > somehow I feel it smells (I need this amount of code because
> > each
> > > > step
> > > > > > > > in the fluent interface above returns a different object via
> > > > interface
> > > > > > > > (e.g. IFindQueryPart).
>
> > > > > > > > One important thing is that the SetupResult must chain the
> > methods
> > > > in
> > > > > > > > exactly the way they've been chained in the call (for example
> > Order
> > > > > > > > must be chained to Group and not vice versa).
>
> > > > > > > > Now to aid this, I've written a Lambda expression inspector
> > (simple
>
> ...
>
> read more ยป
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Rhino Tools Dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rhino-tools-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to