Resetting a mock
Mocks, or just their recorded invocations, can be reset.
How does it work?
Moq records all invocations that happen on a mock. This record can be
cleared using mock.Invocations.Clear()
(or using the obsolete method
mock.ResetCalls()
). This will also “unmatch” setups that have already
matched by one or more of the recorded calls.
A mock can be completely reset via mock.Reset()
. This will remove not
just the recorded invocations, but also all setups and event handlers.
Why does this feature exist?
I suspect there are two reasons why this feature exists:
-
Recording all invocations could be problematic in cases where a mock gets invoked a lot. All invocations get logged (for later verification), and that uses up memory. If verification isn’t going to be needed, that memory is essentially wasted. So sometimes it may be necessary to periodically clear the invocation log so one won’t run into a low memory situation.
-
Mock reuse is desired. Create a mock, set it up, use it; then reset it and use it for something else. This saves one the trouble of creating and setting up two mocks.
What’s wrong with it?
I think that there are potentially better solutions for both cases than the ability to reset a mock.
In the case of (1), it would be better if Moq allowed one to opt-out of
recording all invocations, e.g. through an additional MockBehavior
flag:
new Mock<Foo>(MockBehavior.Loose | MockBehavior.DontRecordInvocations)
Maybe this would end up somewhat differently, but you get the idea. By being able to disable the invocation log, one wouldn’t be in danger of low memory situations due to unneeded invocations sticking around.
With regard to (2), creating another mock and setting it up shouldn’t be a big hassle. One can always extract the creation and setting up of a fresh mock into a function that can be called as many times as needed.
Removal
Removing this feature was fairly easy; I’ve done so in f7a9c0c (approx. 250 lines of code removed).
I also like the fact that we’re getting rid of two methods in
SetupCollection
: Clear
and Reset
. It probably wasn’t very obvious
why two similar methods were needed. (The former would remove setups;
the latter would only “unmatch” them.)