MoqAutoMocker.Get not working as expected

74 views
Skip to first unread message

JamieG

unread,
Jun 2, 2009, 10:27:24 PM6/2/09
to structuremap-users
I'm trying to use the MoqAutoMocker like I've seen the RhinoAutoMocker
used in the example at

http://structuremap.sourceforge.net/AutoMocker.htm#section1

Specifically the section that says you can get access to the mock
version of a dependency by using code like

// This retrieves the mock object for IMockedService
autoMocker.Get<IMockedService>().AssertWasCalled(s => s.Go());

I have a class SignInController that depends on an ISecurityService in
the constructor. I'd like to use the Moq Setup method to set some
expected return values for the ISecurityService.ValidateLogin method,
so I'm expecting to be able to do this

var autoMocker = new MoqAutoMocker<SignInController>();
autoMocker.Get<ISecurityService>().Setup(ss => ss.ValidateLogin
(It.IsAny<string>(), It.IsAny<string>())).Returns
(ValidateLoginResult.Success);

But I never get any intellisense for the .Setup method but I do get
intellisense for the actual ValidateLogin method on the
ISecurityService interface. I'm expecting to get back a version of
Mock<ISecurityService> that lets me setup my expectations, as if I had
done this.

var mockSecurityService = new Mock<ISecurityService>();
mockSecurityService.Setup(ss => ss.ValidateLogin(It.IsAny<string>(),
It.IsAny<string>())).Returns(ValidateLoginResult.Success);

var signInControllerUnderTest = new SignInController
(mockSecurityService);


I've tried this with both RhinoAutoMocker.Get<T> and
MoqAutoMocker.Get<T> and I can never get intellisense for any methods
other than those implemented by T.

Am I doing something wrong?



Jeremy D. Miller

unread,
Jun 3, 2009, 3:30:32 PM6/3/09
to structure...@googlegroups.com
Nope, you're doing fine.  With RhinoMocks, all the Setup/Expect business is an extension method against "object", so Get<T>() works just fine in that scenario (and you've probably guessed that the AutoMocker was written with RhinoMocks in mind).

In your testing code, why don't you add this:

public static class MoqAutoMockerExtensions
{
    public static Mock<T> GetMock<T>(this MoqAutoMocker mocker)
    {
        return mocker.Get<T>() as Mock<T>;
    }
}

and then always use GetMock<T>() for Moq usage.
 
Jeremy D. Miller
The Shade Tree Developer
jeremy...@yahoo.com



From: JamieG <jamie....@gmail.com>
To: structuremap-users <structure...@googlegroups.com>
Sent: Tuesday, June 2, 2009 9:27:24 PM
Subject: [sm-users] MoqAutoMocker.Get not working as expected

Jamie Gaines

unread,
Jun 3, 2009, 9:34:12 PM6/3/09
to structuremap-users
Hi, Jeremy.

Thanks for the reply, but I still can't get this to work. The
extension you suggested didn't work because the compiler was asking
for the type parameter on the "this MoqAutoMocker mocker" parameter,
so I changed the extension method to

public static class MoqAutoMockerExtensions
{
public static Mock<T> GetMock<T>(this MoqAutoMocker<T> mocker)
{
return mocker.Get<T>() as Mock<T>;
}
}

and the compiler was happy.

This of course didn't work as it was always trying to return the mock
for the class under test. So if I had the code...

var autoMocker = new MoqAutoMocker<SignInController>();
autoMocker.GetMock<ISecurityService>().Setup(ss => ss.ValidateLogin
(It.IsAny<string>(), It.IsAny<string>())).Returns
(ValidateLoginResult.Success);

I would get an invalid cast exception of "can't cast type of
Mock<SignInController> to Mock<ISecurityService>".

So then I fumbled around with the generics syntax for a while until I
could find something the compiler was happy with and came up with
this...

public static class MoqAutoMockerExtensions
{
public static Mock<R> GetMock<R, T>(this MoqAutoMocker<T> mocker)
where R : class where T : class
{
return mocker.Get<R>() as Mock<R>;
}
}

This made my call to GetMock a little more clumsy, as below

var autoMocker = new MoqAutoMocker<SignInController>();
autoMocker.GetMock<ISecurityService, SignInController>().Setup(
ss => ss.ValidateLogin(It.IsAny<string>(), It.IsAny<string>
())).Returns(ValidateLoginResult.Success);

since I have to include the SignInController again in the call to
GetMock, but again, it made the compiler happy.

The problem is that this still doesn't work. Trying to cast the
mocker.Get<R> as Mock<R> just doesn't work. I keep getting null
reference exceptions. If I look at the return value of mocker.Get<R>
in the debugger it shows a return type of
{ISecurityServiceProxyec205051a8d74b03a465cde5c4172efc} which is the
proxy object created by Moq.

There's seemingly no way for me to get to the Mock<R> interface this
way. I also tried looking at some of the other methods and properties
exposed by MoqAutoMocker<T> and those didn't seem to get me anywhere
either. I'm admittedly new to all this so I'm not sure if I'm missing
something obvious or not.

At this point I'd take any way you can suggest to get access to the
Mock<T> objects that the AutoMocker creates for the dependencies. I
just can't seem to figure out how to do it.

Thanks!

Jamie






On Jun 3, 3:30 pm, "Jeremy D. Miller" <jeremydmil...@yahoo.com> wrote:
> Nope, you're doing fine.  With RhinoMocks, all the Setup/Expect business is an extension method against "object", so Get<T>() works just fine in that scenario (and you've probably guessed that the AutoMocker was written with RhinoMocks in mind).
>
> In your testing code, why don't you add this:
>
> public static class MoqAutoMockerExtensions
> {
>     public static Mock<T> GetMock<T>(this MoqAutoMocker mocker)
>     {
>         return mocker.Get<T>() as Mock<T>;
>     }
>
> }
>
> and then always use GetMock<T>() for Moq usage.
>
>  Jeremy D. Miller
> The Shade Tree Developer
> jeremydmil...@yahoo.com
>
> ________________________________
> From: JamieG <jamie.gai...@gmail.com>
Reply all
Reply to author
Forward
0 new messages