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.