How to stub a stubborn object [long]

17 views
Skip to first unread message

ikr...@gmail.com

unread,
Feb 21, 2009, 8:12:26 PM2/21/09
to Rhino.Mocks
Let's say I have class A that depends on class D [for "dependency"].

Short question: if D is derived from MarshalByRefObject, I can mock
it, but I cannot stub it without creating an actual instance of D.
With the emphasis on stubs in new Rhino.Mocks this becomes a pain in
the neck. How do you suggest to get around it? Write a patch that
would extend stub functionality to MarshalByRefObjects? :-)

The long part: why would I need it in the first place?

There are two primary cases. One is when D is a class that I don't
control, something like Graphics. Another case is when I do control D,
but I don't want to create a real of instance of it: either because it
is heavy, or because I do not want to entangle myself with D's
dependencies when I am unit testing A.

Of course, if I control D, I could extract an interface from it (D:
IPublicStuffInD) and make A depend on that. In some cases it makes
sense, in others it doesn't. If D is something rather ad hoc and
unique (i.e. multiple implementations of IPublicStuffInD are not
likely), extracting an instance would only cause duplication. Every
time I need to change public interface of D, I will have to do it in
two places. Not cool.

Before Rhino Mocks 3.5, my favorite technique was to make D derive
from MarshalByRefObject, and voila - you can mock it without creating
a real instance, or worrying about D's dependencies. But what about
stubs?

As it was pointed out multiple times, it is possible to emulate stubs
with mocks, but it gets hairy pretty quickly. This also violates the
rule of least astonishment: I am actually creating a stub, but I am
doing it via CreateMock() method. Looks confusing.

Any thoughts/advise would be greatly appreciated.
Also, sorry if this question has been asked before - admittedly, I did
not read through all the archives.

Ayende Rahien

unread,
Feb 21, 2009, 8:38:45 PM2/21/09
to Rhino...@googlegroups.com
I am afraid that I am at a loss to understand what you mean "you can't stub it"

ikr...@gmail.com

unread,
Feb 21, 2009, 9:37:01 PM2/21/09
to Rhino.Mocks
On Feb 21, 8:38 pm, Ayende Rahien <aye...@ayende.com> wrote:
> I am afraid that I am at a loss to understand what you mean "you can't stub
> it"
>

class D : MarshalByRefObject
{
public D( Dependency1 d1, Dependency2 d2 )
{
Start_Nuclear_Reactor();
}
}

class A
{
public A( D dependency )
{
...
}
}

[Test]
public void Test_Something_In_A()
{
var d = MockRepository.CreateStub<D>(); // will fail - wants
constructor arguments!!!
var a = new A(d);
}

Now, to create a stub of D, I must produce d1 and d2. And then d3, d4,
and d5. should D change to require more dependencies. And, every time
I do it will start the nuclear reactor :-)

I hope this explains my problem.

ikr...@gmail.com

unread,
Feb 21, 2009, 9:55:07 PM2/21/09
to Rhino.Mocks
On Feb 21, 9:37 pm, "ikri...@gmail.com" <ikri...@gmail.com> wrote:

>      var d = MockRepository.CreateStub<D>(); // will fail - wants
> constructor arguments!!!

That's GenerateStub.
In other words, you cannot stub WITHOUT CREATING AN INSTANCE OF D.
Consider this:

MockRepository.GenerateMock<ISomeInterface>(); // works
MockRepository.GenerateStub<ISomeInterface>(); // works
MockRepository.GenerateMock<D>(); // works, via remoting proxy
MockRepository.GenerateStub<D>(); // fails

Ayende Rahien

unread,
Feb 21, 2009, 10:13:17 PM2/21/09
to Rhino...@googlegroups.com
Can you create a failing test?
I can't think of a reason in which this would be the case, since both GenerateMock and GenerateStub goes through the same code path for creating the mocked instance.

ikr...@gmail.com

unread,
Feb 21, 2009, 11:02:13 PM2/21/09
to Rhino.Mocks
>
> Can you create a failing test?

Sure thing. I looked in the code in SVN, I think these are different
code paths.
But I may be wrong.

Here's the test fixture. The first test is OK, the second fails on
Rhino Mocks version 3.5.0.1337.
Exception:
Rhino.Test.CreateMockAndCreateStub.GenerateStub_Works_With_MarshalByRef:
System.MissingMethodException : Can't find a constructor with matching
arguments
----> System.MissingMethodException : Constructor on type
'DProxy3ff1879607fb420c977fdfd1a946a45b' not found.

=======================================================

using System;
using NUnit.Framework;
using Rhino.Mocks;

namespace Rhino.Test
{
public class D : MarshalByRefObject
{
public D(IConvertible dep1, IDisposable dep2, ICloneable dep3)
{
}
}

[TestFixture]
public class CreateMockAndCreateStub
{
[Test]
public void GenerateMock_Works_With_MarshalByRef()
{
var d = MockRepository.GenerateMock<D>();
}

[Test]
public void GenerateStub_Works_With_MarshalByRef()
{
var d = MockRepository.GenerateStub<D>();
}
}
}

Ayende Rahien

unread,
Feb 21, 2009, 11:34:15 PM2/21/09
to Rhino...@googlegroups.com
Wow, you are correct.
A simple fix, and it is in the repository

ikr...@gmail.com

unread,
Feb 22, 2009, 10:09:18 AM2/22/09
to Rhino.Mocks
On Feb 21, 11:34 pm, Ayende Rahien <aye...@ayende.com> wrote:
> Wow, you are correct.
> A simple fix, and it is in the repository
>

Thanks!
Reply all
Reply to author
Forward
0 new messages