tags:

views:

1109

answers:

6

I am attempting to mock a call to an indexed property. I.e. I would like to moq the following:

object result = myDictionaryCollection["SomeKeyValue"];

and also the setter value

myDictionaryCollection["SomeKeyValue"] = myNewValue;

I am doing this because I need to mock the functionality of a class my app uses.

Does anyone know how to do this with MOQ? I've tried variations on the following:

Dictionary<string, object> MyContainer = new Dictionary<string, object>();
mock.ExpectGet<object>( p => p[It.IsAny<string>()]).Returns(MyContainer[(string s)]);

But that doesn't compile.

Is what I am trying to achieve possible with MOQ, does anyone have any examples of how I can do this?

A: 

Wouldn't it be easier to just use a stub object? Set the required values and check the indexes you need.

Søren Spelling Lund
That is what I have done in the meantime - I'm just curious as to whether it is possible or not with MOQ.
Ash
+2  A: 

I've asked this question before on the Moq discussion forums.

I haven't tried it but Dan (Moq author) says it works.

CVertex
+4  A: 

It's not clear what you're trying to do. You don't show the declaration of the mock. Are you trying to mock a dictionary?

MyContainer[(string s)] isn't valid C#.

This compiles:

        var mock = new Mock<IDictionary>();
        mock.SetupGet( p => p[It.IsAny<string>()]).Returns("foo");
Mike Scott
this works as well. except the new syntax uses `SetupSet` instead of `ExpectGet`. also works for setters as well.
tmont
tmont, thanks - edited to new syntax.
Mike Scott
A: 

It appears that what I was attempting to do with MOQ is not possible.

Essentially I was attempting to MOQ a HTTPSession type object, where the key of the item being set to the index could only be determined at runtime. Access to the indexed property needed to return the value which was previously set. This works for integer based indexes, but string based indexes do not work.

Ash
+3  A: 

Ash, if you want to have HTTP Session mock, then this piece of code does the job:

/// <summary>
/// HTTP session mockup.
/// </summary>
internal sealed class HttpSessionMock : HttpSessionStateBase
{
    private readonly Dictionary<string, object> objects = new Dictionary<string, object>();

    public override object this[string name]
    {
        get { return (objects.ContainsKey(name)) ? objects[name] : null; }
        set { objects[name] = value; }
    }
}

/// <summary>
/// Base class for all controller tests.
/// </summary>
public class ControllerTestSuiteBase : TestSuiteBase
{
    private readonly HttpSessionMock sessionMock = new HttpSessionMock();

    protected readonly Mock<HttpContextBase> Context = new Mock<HttpContextBase>();
    protected readonly Mock<HttpSessionStateBase> Session = new Mock<HttpSessionStateBase>();

    public ControllerTestSuiteBase()
        : base()
    {
        Context.Expect(ctx => ctx.Session).Returns(sessionMock);
    }
}
Nice one - this was just what I needed +1
Ian Oxley
A: 

I can set and obtain the value. Well, there are some problems returning the value. Have a look here

http://stackoverflow.com/questions/1642631/moq-mocking-and-tracking-session-values

seanlinmt