69

I'm currently confuse on how to mock.

I'm using Moq. To mock objects I usually write this way

 var mockIRepo = new Mock<IRepo>();

However, I need to create mock object for my setup.

Option1 Is it better to mock my object which only contain properties this way?

 var object = Mock.Of<Object>()

Option2 Or this way

 var object = new Mock<Object>()

I've read that option 2 has setupproperties which is kinda questionable to me because I could also set the properties in option 1.

Then what is the difference? Or is there a better way?

choopau
  • 2,209
  • 5
  • 21
  • 28

7 Answers7

74

This post helped me to understand Mock.Of<T> : Old style imperative Mock<T> vs functional Mock.Of<T>

As explained in the post, with Mock.Of<T> you're saying "Give me a mock that behaves like this" (or Mocks.Of<T> if you need to get many objects (IEnumerable)). It makes the declaration of a mock more concise.

Example with Mock<T> (returns a Mock)

var el1 = new Mock<IElementInfo>();
el1.Setup(x => x.Id).Returns(Guid.NewGuid());
el1.Setup(x => x.Multiplicity).Returns(Multiplicity.Single);

var c1 = new Mock<ICollectionInfo>();
c1.Setup(x => x.Id).Returns(Guid.NewGuid());
c1.Setup(x => x.Multiplicity).Returns(Multiplicity.Multiple);

var p1 = new Mock<IPropertyInfo>();
p1.Setup(x => x.Id).Returns(Guid.NewGuid());
p1.Setup(x => x.Name).Returns("Foo" + Guid.NewGuid().ToString());
p1.Setup(x => x.Type).Returns("System.String");

var p2 = new Mock<IPropertyInfo>();
p2.Setup(x => x.Id).Returns(Guid.NewGuid());
p2.Setup(x => x.Name).Returns("Bar" + Guid.NewGuid().ToString());
p2.Setup(x => x.Type).Returns("System.String");

var elementInfoMock = new Mock<IElementInfo>();
elementInfoMock.Setup(e => e.Id).Returns(Guid.NewGuid());
elementInfoMock.Setup(e => e.Multiplicity).Returns(Multiplicity.Multiple);
elementInfoMock.Setup(e => e.Elements)
    .Returns(new List<IAbstractElementInfo>
    {
        el1.Object,
        c1.Object,
    });
elementInfoMock.Setup(x => x.Properties).Returns(
    new List<IPropertyInfo>
    {
        p1.Object,
        p2.Object,
    });

this.elementInfo = elementInfoMock.Object;

Same example using Mock.Of<T> (returns an instance of the class)

this.elementInfo = Mock.Of<IElementInfo>(x =>
x.Id == Guid.NewGuid() &&
x.Multiplicity == Multiplicity.Multiple &&
x.Elements == new List<IAbstractElementInfo>
{
    Mock.Of<IElementInfo>(e => e.Id == Guid.NewGuid() && e.Multiplicity == Multiplicity.Single),
    Mock.Of<ICollectionInfo>(e => e.Id == Guid.NewGuid() && e.Multiplicity == Multiplicity.Single),
} &&
x.Properties == new List<IPropertyInfo>
{
    Mock.Of<IPropertyInfo>(p => p.Id == Guid.NewGuid() && p.Name == "Foo" + Guid.NewGuid() && p.Type == "System.String"),
    Mock.Of<IPropertyInfo>(p => p.Id == Guid.NewGuid() && p.Name == "Foo" + Guid.NewGuid() && p.Type == "System.String"),
});
19

Based on the answers above, I guess when you mostly want to mock properties, Mock.Of<T>() is easier, whereas when you want to mock methods etc., Mock<T> is easier.

  • Mostly mocking properties:
var foo = Mock.Of<Foo>();
foo.Property1 = 1;
foo.Property2 = 2;
foo.Property3 = 3;
  • Mostly mocking methods:
var barMock = new Mock<Bar>();
barMock.Setup(bar => bar.GetValue1()).Returns(1);
barMock.Setup(bar => bar.GetValue2Async()).ReturnsAsync(2);
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
6

Both do the same but with Mock.Of it's more "natural" code.

Using Mock<T> looks more like this (or with Setup/Return like your code):

var mockService = new Mock<ISomeService>();
mockService.SetupProperty(s => s.IsActive);
mockService.Object.IsActive = true;
mockService.SetupProperty(s =>s.DelayTime);
mockService.Object.DelayTime = 5000;

Using Mock.Of<T> you get directly the instance and you can set the value you want. And you can use Mock.Get() to configure any method:

var mockService = Mock.Of<ISomeService>();
mockService.IsActive = true;
mockService.DelayTime = 5000;
Mock.Get(mockService).Setup(s => s.ExecuteTask()).Returns(true);

They do the same, but for more complex services with a lot of properties and methods, I think Mock.Of<T> is more readable

Isaac Ojeda
  • 285
  • 4
  • 11
  • 3
    Your example code for `Mock.Of<>()` only works if `ISomeService` has setters for `IsActive` and `DelayTime`. If it doesn't, declare like this: `var mockService = Mock.Of(mockService => mockService.IsActive == true && mockService.DelayTime == 5000);` – Artemious Oct 16 '20 at 07:54
1

While the newer Mock.Of looks better and requires less coding, it does have limitations (as others have already pointed out).

However, it is indeed possible to do it via Mock.Get().

For example, consider trying to get a mock with default values mocked, however there is no DefaultValue = DefaultValue.Mock on Mock.Of(), so in this case the following can be done:

var obj = Mock.Of<MyType>(t => SomeProp == Mock.Of<PropType>());

// We want SomeProp all sub properties to return mocks
Mock.Get(obj.SomeProp).DefaultValue = DefaultValue.Mock;

// Note that the following step wouldn't be required when using new Mock{DefaultValue = DefaultValue.Mock}
Mock.Get(obj.SomeProp).SetupAllProperties();
yoel halb
  • 12,188
  • 3
  • 57
  • 52
0

The big difference I have noticed is that while Mock.Of<T>(m => m.SomeMethod() == someResult) is, IMHO, easier to use and much more readable, you can't set up methods to throw exceptions like you can using the old syntax - e.g. new Mock<T>.Setup(m => m.SomeMethod()).Throws<Exception>();

So you have to use the old way sometimes.

NOTE - If I am mistaken in this, please correct me, but I was not able to find anything on how to do this with the Mock.Of<T> syntax. To be fair, I only searched for about 10m, but...yeah.

Mike Loux
  • 706
  • 2
  • 11
  • 23
0

You can mock async methods like this using the Mock.Of syntax

var mockService = Mock.Of<ISomeService>(x => x.SomeMethodAsync() == Task.FromResult(myMockResults));
stevie_c
  • 990
  • 1
  • 8
  • 15
0

I believe this post lacks a summary:

Mock.Of<Object>() returns the mocked instance of Object (the "mockee" if you want), while new Mock<Object>() returns the "mocker".

1. Better readability of Mock.Of<Object>() esp. for mocking properties.

2. Mock<Object>() is a lot more flexible. To access the full functionality, though, you need the mocker instead of the mocked instance. Among these features are:

  • Read-only properties. I want to add: you can mock read-only properties with new Mock<IReadOnlyObject>() but not with Mock.Of<Object>().

  • Exceptions. Methods throwing exceptions can be done with new Mock<Object>.Setup(m => m.SomeMethod()).Throws<Exception>();.

  • Sequences. You can set up sequences of events.

   var mock = new Mock<IObject>();
   mock.SetupSequence(m => m.GetCount())
       .Returns(3)  // will be returned on 1st invocation
       .Returns(2); // will be returned on 2nd invocation
  • Callbacks.

etc.


Mock.Of<Object>() can overcome these disadvantages using Mock.Get(Mock.Of<Object>()). Now you can use Setup, SetupSequence, etc. But it's a detour and we lose the advantage of readability.

The other way round, we can directly set properties of the mocked instance with mock.Object (see below). It will not work with MockBehavior.Strict, though, while setting the property using Mock.Of<Object>() will work also work for strict mocks.

   var mock = new Mock<IObject>();
   mock.Object.SomeProperty = 5;

Feel free to add more insight to this summary

Jan
  • 4,974
  • 3
  • 26
  • 43