Unit Testing: Moq doesn’t support property indexers
I hit a road block today writing some tests which were dependent upon another class’s property indexer. When trying to do the following using Moq:
1: [TestMethod]
2: public void Test1()
3: {
4: Mockcontext = new Mock ();
5:
6: Object actual = null;
7:
8: context.ExpectSet(c => c.Session["SomeKey"]).Callback(o => actual = o);
9:
10: context.Object.Session["SomeKey"] = "some value";
11:
12: Assert.IsNotNull(actual, "Value was not set");
13: }
Line 8 fails with this error:
System.ArgumentException: Expression is not a property access: c => c.Session.get_Item(“SomeKey”).
It appears the current stable build of Moq (version 2.6.1014.1) . The good news is that a few days ago support was added for property indexers
///
/// Mock implementation of HttpSessionStateBase
///
///
/// Current stable build of Moq (2.6.1014.1) doesn't support property indexers
/// at this time, so this is an implementation of HttpSessionStateBase
/// which allows us to verify that the session cache is being updated.
///
internal class MockSession : HttpSessionStateBase
{
Dictionarysession = new Dictionary ();
public override void Add(string name, object value)
{
session.Add(name, value);
}
public override object this[string name]
{
get
{
if (!session.ContainsKey(name))
return null;
return session[name];
}
set
{
session[name] = value;
}
}
}
Then you can do the following:
// setup
MockSession session = new MockSession();
Mockcontext = new Mock ();
context.ExpectGet(c => c.Session).Returns(session);
// exercise
context.Session["SomeKey"] = "some value";
// assert
Assert.IsNotNull(context.Session["SomeKey"]);
Happy Moqing!