Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Moq how to get all method invocations

I am creating a mock of an interface via moq.

My application's code is calling different methods of my mock with different combination of inputs. When I do verify() with wrong inputs then an exception is thrown that lists out all method invocations.

I want to get those method invocations, perform some clean up and display to the user in a different format. Is it possible to get all method invocations before calling verify?

Sample code:

var mock = new Mock<ILoveThisFramework>();


  mock.Setup(framework => framework.DownloadExists("2.0.0.0"))
      .Returns(true);

  // Hand mock.Object as a collaborator and exercise it, 
  // like calling methods on it...
  ILoveThisFramework lovable = mock.Object;
  bool download = lovable.DownloadExists("2.0.0.0");

  // Verify that the given method was indeed called with the expected value at most once

// it will throw exception which will include method invocations. I want to get method invocations out and reformat them. 

  mock.Verify(framework => framework.DownloadExists("3.0.0.0"), Times.AtMostOnce());
like image 232
InfoLearner Avatar asked Dec 09 '17 16:12

InfoLearner


1 Answers

The upcoming next major iteration of Moq, version 5, will allow this kind of mock inspection.

Update: Starting with Moq 4.9 you will be able to inspect all recorded invocations of a mock via a new Mock.Invocations collection property.

As of version 4.8.2, Moq does not allow you to get hold of all recorded invocations, because the collection that holds those (Mock.Invocations) is not declared public.

Exposing Mock.Invocations in Moq 4 would actually be a fairly simple change. We're investigating it; see this pull request on GitHub. (This has since happened, see update comment above.)

You could in theory use reflection to get at that private data, but I don't recommend this approach. Private bits are private for a reason. They are not part of the public contract, and are therefore subject to change without notice.

If it is just one setup you're dealing with, you can simply capture argument values, like this answer suggests.

var someMethodArgs = new List<TArg>();
mock.Setup(m => m.SomeMethod(arg: Capture.In(someMethodArgs)));
like image 184
stakx - no longer contributing Avatar answered Sep 26 '22 21:09

stakx - no longer contributing