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: Mock<HttpContextBase> context = new Mock<HttpContextBase>();
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) doesn’t support property indexers. The good news is that a few days ago support was added for property indexers. However, if you’re like me and you’re not working with the latest and greatest, then there’s a workaround. Just create your own mock implementation of the class with the indexed property. In my case the class in question was HttpSessionStateBase. Here’s my mock implementation:
/// <summary> /// Mock implementation of HttpSessionStateBase /// </summary> /// <remarks> /// 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. /// </remarks> internal class MockSession : HttpSessionStateBase
{ Dictionary<string, object> session = new Dictionary<string, object>();
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(); Mock<HttpContextBase> context = new Mock<HttpContextBase>(); context.ExpectGet(c => c.Session).Returns(session);
// exercise context.Session["SomeKey"] = "some value";
// assert Assert.IsNotNull(context.Session["SomeKey"]); Happy Moqing!
Labels: Moq, Unit Testing

