Andreas,

While I do see your point, I don't think this is a feature I would use
personally.  It's probably because I'm more of a control freak -- I
want things nice and clear and explicit.  If a mock framework is going
to dynamically/recursively "fill-in" missing object references, it
could hide some missing object initialization that my code was
supposed to be doing.  I'd prefer to create all of those stubs myself.

But it is an interesting idea.

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



On Fri, May 28, 2010 at 5:48 AM, haifisch <[email protected]> wrote:
> Hello Patrick,
>
> it's not really a problem - because as mentioned it's easy to solve.
> It's more like an imperfection :-)
>
> Let me show you my code...
>
> internal class NetworkServiceAdapter
>    public NetworkSerivceAdapter(Uri connectUri, string userName,
> string password)
>      : this(new ConnectionFactory(connectUri) { UserName = userName,
> Password = password })
>    {
>    }
>
>    /// <remarks>
>    /// This constructor frees the implementation of the class from
> any concrete dependency.
>    /// It is implemented to allow tests to implement test stubs (e.g.
> saboteurs).
>    /// </remarks>
>    internal NmsAdapter(IConnectionFactory factory)
>    {
>      // store factory for later use!
>      this.factory = factory;
>
>      this.InitializeSomethingElse();
>    }
> }
>
> The existing test in pseudo-code:
>
> [Test]
> public void TestSomethingElseInitialization()
> {
>   var factory = MockRepository.GenerateStub<IConnectionFactory>(); //
> this object doesn't matter in this test!
>
>   var sut = new NetworkServiceAdapter(factory);
>
>  Assert whatever is initialized by "InitializeSomethingElse".
> }
>
> Now consider i have a new requirement - i should configure the
> RedelivieryPolicy of the factory.
>
> So i first write a new test:
>
> [Test]
> public void RedeliveryPolicyIsSetAsExpected()
> {
>    var factory = MockRepository.GenerateStub<IConnectionFactory>();
>    var policy = MockRepository.GenerateMock<IRedeliveryPolicy>();
>    factory.Stub(x=>x.RedeliveryPolicy).Returns(policy);
>
>    policy.Expect(x=>x.MaxRedeliveries = 5);
>
>    var sut = new NetworkServiceAdapter(factory);
>
>   policy.VerifyAllExpectations();
> }
>
> Now I'll add the following line after 'this.factory = factory;' to
> satisfy my test...
> this.factory.RedeliveryPolicy.MaxRedeliveries = 5;
>
> Now my old test fails and i must adapt it. Sure this is quite easy to
> fix. But why must I do that?
> I'll think the Problem is that 'null' is not a good default value for
> any reference type.
>
> So i would like to see a feature that generates a recursive mock stub.
> If i could had use something like "var factory =
> MockRepository.GenerateRecursiveStub<IConnectionFactory>();" it didn't
> have to adapt this test after implementing the new feature.
>
> Maybe I'm doing something completely wrong? Or have i missed a basic
> design principle?
>
> Andreas
>
> On 27 Mai, 16:37, Patrick Steele <[email protected]> wrote:
>> Andreas,
>>
>> I'm still not clear on what issue you're trying to solve.  I see the
>> "recursive" property issue, but since stubbing a property is so easy,
>> I don't see where the extra overhead is.
>>
>> Could you give a more concrete example of where this is causing you
>> pain in your testing?
>>
>> Thanks.
>>
>> ---
>> Patrick Steelehttp://weblogs.asp.net/psteele
>>
>> On Thu, May 27, 2010 at 10:27 AM, haifisch <[email protected]> wrote:
>> > Hi Patrick,
>> > interesting idea - maybe i try a similar approach next time i need a
>> > 'recursive-stub'.
>> > You're absolutly right with your assumption about the properties - as
>> > always real world is more complicated ;-)
>>
>> > I also understood the argument with the untested parts. But especially
>> > if that parts are tested with other test (e.g. there are mocks that
>> > verify some expectations on that object) and now i have another test
>> > that wants to test a completely other expectation - this test just
>> > ignores the 'recursive-stub'.
>>
>> > Imagine that a new property is introduced into the existing interface.
>> > I'll also write a new test to verify that fake.NewProperty.XYZ=5 is
>> > set. By why must i adapt old test code to now also stub the
>> > NewProperty?
>>
>> > So my hope was that if had a 'recursive-stub' in the old test - i
>> > didn't have to adapt old code if a new property is used in the
>> > production code.
>>
>> > O.k. i think my that explanation was confuse - i hope you can
>> > follow ;-)
>>
>> > Andreas
>>
>> > On 27 Mai, 14:05, Patrick Steele <[email protected]> wrote:
>> >> Not that I know of.  Is is really that hard to add one more line?
>>
>> >> fake.SomeProperty = MockRepository.GenerateStub<PropertyType>();
>>
>> >> I guess if you had a lot of properties, it might become cumbersome.
>> >> Then again, if you've got a lot of properties you're calling methods
>> >> on, they're probably an important part of the class you're testing and
>> >> you may want to set some expectations on them.
>>
>> >> It is an interesting idea.  I played around with trying to create an
>> >> extension method that would use reflection to recursively generate
>> >> stubs, but there's some tricky issues (like how to set a return value
>> >> on a read-only property without using a lambda).  And the recursive
>> >> nature of the stubbing caused an issue too.
>>
>> >> public static void StubDeep<T>(this T mock) where T:class
>> >> {
>> >>         Type t = typeof (T);
>> >>         foreach (var prop in t.GetProperties(BindingFlags.Public |
>> >> BindingFlags.Instance).Where(prop => !prop.PropertyType.IsSealed))
>> >>         {
>> >>                 var subMock = 
>> >> MockRepository.GenerateStub(prop.PropertyType);
>> >>                 if (prop.CanWrite)
>> >>                 {
>> >>                         prop.SetValue(mock, subMock, new object[] {});
>> >>                 }
>> >>                 else
>> >>                 {
>> >>                         //TOOD: How to set up a Stub() on a just a 'Type'
>> >>                         // and a 'PropertyInfo'?  I.e. no lambda.
>> >>                         //mock.Stub(m => m.Property).Return(subMock);
>> >>                 }
>>
>> >>                 // this doesn't work as the typeof "subMock" is
>> >>                 // reported as "Object" inside StubDeep().
>> >>                 subMock.StubDeep();
>> >>         }
>>
>> >> }
>>
>> >> There may be easy fixes for those two issues, but I haven't played
>> >> around much with reflection on generic types.
>>
>> >> ---
>> >> Patrick Steelehttp://weblogs.asp.net/psteele
>>
>> >> On Thu, May 27, 2010 at 4:47 AM, haifisch <[email protected]> wrote:
>> >> > Hello,
>>
>> >> > is there a simple way to create a recursive stub in RhinoMocks?
>> >> > Some thing like TypeMock's fake.
>>
>> >> > var fake = Isolate.Fake.Instance<SomeType>();
>>
>> >> > //code under test can
>>
>> >> > fake.SomeProperty.DoSomething()
>>
>> >> > //or
>>
>> >> > var propObj = fake.SomeProperty;
>> >> > propObj.DoSomething();
>>
>> >> > (http://weblogs.asp.net/rosherove/archive/2009/07/09/minimizing-unit-
>> >> > test-fragility-8-features-in-typemock-isolator-to-help.aspx)
>>
>> >> > I'm aware that there are only special cases where such a feature might
>> >> > make sense, but sometimes i just want stub a parameter object -
>> >> > without any expectations on its usage.
>>
>> >> > Best regards,
>>
>> >> > Andreas
>>
>> > --
>> > 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].
>> > To unsubscribe from this group, send email to 
>> > [email protected].
>> > For more options, visit this group 
>> > athttp://groups.google.com/group/rhinomocks?hl=en.
>
> --
> 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].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group at 
> http://groups.google.com/group/rhinomocks?hl=en.
>
>

-- 
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].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rhinomocks?hl=en.

Reply via email to