Mocking indexer getters with Moq
This is a follow-up on that other post: Mocking indexer setters with Moq.
So thanks to that post, we now know how to intercept the setting of a particular indexed property (in our example, an application variable) and set a local variable with the value that was set by the tested code.
Now if you want the application to return that same value when queried by the tested code, you also need to mock the indexer getter.
This operation is also not entirely trivial. Here’s how you do it: you do a SetupGet chained with a Returns with a lambda expression as the parameter:
.SetupGet(c => c.Application["foo"])
.Returns(() => (object)map);
That last point about using a lambda is pretty important. If you just use map as the parameter for Returns, Moq will hold on to a reference to whatever object map contained at the time the call to Returns is made. This might very well be null, if you started with the code in our previous setter example. If you use a lambda on the other hand, Moq will not hold on to the value of map but to the expression that returns the value of map. The execution is deferred. Now every time the tested code exercises that path, Moq will evaluate the expression, which will return the current value of map.
Also of interest, whereas we had to explicitly have an index parameter for the callback lambda in the case of the setter, Returns needs no such thing, and this example actually has little code that is specific to indexed properties. The trick about the lambda in the Returns in particular applies just as well to mocking getters for non-indexed properties.