Skip to content

Mocking

It's important to understand the difference between Moq behavior and Microsoft guidelines.

Warning

Moq does not separate stub and mock objects. It uses MockBehavior enumeration instead.

Fake - A fake is a generic term that can be used to describe either a stub or a mock object. Whether it's a stub or a mock depends on the context in which it's used. So in other words, a fake can be a stub or a mock.

Mock - A mock object is a fake object in the system that decides whether or not a unit test has passed or failed. A mock starts out as a Fake until it's asserted against.

Stub - A stub is a controllable replacement for an existing dependency (or collaborator) in the system. By using a stub, you can test your code without dealing with the dependency directly. By default, a stub starts out as a fake.

Info

Read Let's speak the same language article for more info.

In-Team conventions🔗

  1. Follow Moq naming conventions, because there are differences between Moq.Mock and typical fake\mock\stub terms. All variables should be postfixed with Mock even if you test only object state, because there is still an opportunity for behavior verification.
    var loggerMock = new Mock<ILogger>();
    

Base information🔗

What is possible to mock?

  1. Interfaces
  2. virtual methods
  3. protected methods

What is NOT possible to mock?

  1. Non-virtual methods
  2. static methods. If you want mock this, you should rewrite your code like shown in this workaround

Configuration🔗

Mock internal visible objects🔗

If you want mock internal objects - add the following code to a .csproj which contains internal types:

<ItemGroup>
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
        <_Parameter1>Faro.Connectors.SomeConnectorsTests</_Parameter1>
    </AssemblyAttribute>
</ItemGroup>

Warning

Replace Faro.Connectors.SomeConnectorsTests with your actual test project name.

Info

Read Advanced Features article for more info.

Mock Behavior🔗

There are two types of mock behavior - Loose and Strict.

Loose - default behavior, which never throws and returns default values or empty arrays, enumerables, etc. if no expectation is set for a member.

Strict - a "true Mock", raising exceptions for anything that doesn't have a corresponding expectation.

var mock = new Mock<IFoo>(MockBehavior.Strict);

Usage🔗

Use Mock.Of<T>() when you want to pass mock object without configuration.

var someThing = new SomeThing(Mock.Of<ILogger>());

Use new Mock<T>() when you want setup or verify behavior.

var loggerMock = new Mock<ILogger>();
loggerMock.Setup(...);
var someThing = new SomeThing(loggerMock.Object);
loggerMock.Verify(...);

Setup🔗

Setting up a member to return value on every call.

var mock = new Mock<IFoo>();
mock.Setup(x => x.GetCount()).Returns(1);

var fistCallResult = mock.Object.GetCount();
var secondCallResult = mock.Object.GetCount();

fistCallResult.Should().Be(secondCallResult); //true

Setup sequence🔗

Setting up a member to return different values / throw exceptions on sequential calls:

var mock = new Mock<IFoo>();
mock.SetupSequence(f => f.GetCount())
    .Returns(3)  // will be returned on 1st invocation
    .Returns(2)  // will be returned on 2nd invocation
    .Returns(1)  // will be returned on 3rd invocation
    .Returns(0)  // will be returned on 4th invocation
    .Throws(new InvalidOperationException());  // will be thrown on 5th invocation

Info

Read Miscellaneous article for more info.

Setup async method🔗

Use ReturnsAsync() on your mock.

var mock = new Mock<MyClass>();
mock.Protected()
     .Setup(foo => foo.DoSomethingAsync())
     .ReturnsAsync(1);

Warning

Stay aligned with this, don't use other approaches.

Setup protected method🔗

Call Protected() on your mock, after which you can use the generic Setup<> with the return type of your method.

var mock = new Mock<MyClass>();
mock.Protected()
     .Setup<int>("MyProtectedGetIntMethod")
     .Returns(1);

Setup out parameter🔗

Call Callback() on your mock, in it you could assign out parameter.

var outObject = new object();
var dictionaryMock = new Mock<IDictionary<object, object?>>();
dictionaryMock
    .Setup(c => c.TryGetValue("ConcreteKey", out It.Ref<object>.IsAny))
    .Returns(true)
    .Callback((object _, out object outParameter) => { outParameter = outObject; });

Call base method🔗

Invoke base class implementation if no expectation overrides the member (a.k.a. "Partial Mocks" in Rhino Mocks): default is false.

var mock = new Mock<Foo> { CallBase = true };

Recursive mock🔗

Make an automatic recursive mock: a mock that will return a new mock for every member that doesn't have an expectation and whose return value can be mocked (i.e. it is not a value type)

var mock = new Mock<IFoo> { DefaultValue = DefaultValue.Mock }; // default is DefaultValue.Empty
Bar value = mock.Object.Bar; // this property access would return a new mock of Bar as it's "mock-able"

Info

Read Customizing Mock Behavior article for more info.