Overview
Credit: https://docs.educationsmediagroup.com/unit-testing-csharp/moq Credit: https://softchris.github.io/pages/dotnet-moq.html#creating-our-first-mock
Mocks are configured using the Setup()
and Returns()
methods. This configuration, also known as instruction, tells the mock to answer with a certain response
if a method or property is called.
Some test examples below use this system:
public class Service
{
private readonly IFoo _foo;
public Service(IFoo foo) => _foo = foo ?? throw new ArgumentNullException(nameof(foo));
public void Ping() => _foo.DoSomething("PING");
}
public interface IFoo
{
bool DoSomething(string command);
}
And are arranged like this:
var mock = new Mock<IFoo>();
mock.Setup(p => p.DoSomething(It.IsAny<string>())).Returns(true);
var sut = new Service(mock.Object);
Configuring Method Calls
When the DoSomething()
method is called with argument "ping"
, the method should return true
:
mock.Setup(mock => mock.DoSomething("ping")).Returns(true);
Repeated Calls
To test methods that should have different outcomes when called repeatedly:
mock.SetupSequence(p => p.GetSomething(It.IsAny<string>())
.Returns(1)
.Returns(2)
.Returns(3);
If the method returns void
, replace Returns(arg)
with Pass()
.
out
Parameters
When TryParse()
is called with argument "ping"
, it should set the out
parameter to "ack"
and return true
:
var outString = "ack";
mock.Setup(mock => mock.TryParse("ping", out outString)).Returns(true);
ref
Parameters
Only matches if the ref
argument to the invocation is the same instance:
var instance = new Bar();
mock.Setup(mock => mock.Submit(ref instance)).Returns(true);
Or:
var value = "This is a test value";
mock.Setup(p => p.DoSomething(ref value));
Async Methods
Use the Task’s Result
property:
mock.Setup(mock => mock.DoSomethingAsync().Result).Returns(true);
Or, use ReturnsAsync()
:
mock.Setup(p => p.GetValueAsync()).ReturnsAsync(123);
Methods with Computed Return Values
For this scenario, both Returns()
and ReturnsAsync()
have overloads that accept a delegate:
mock.Setup(p => p.Add(It.IsAny<int>(), It.IsAny<int>())
.Returns((int first, int second) => first + second);
Methods That Throw Exceptions
mock.Setup(p => p.DoSomething()).Throws<Exception>());
mock.Setup(p => p.DoSomethingAsync()).ThrowsAsync(new Exception());
Configuring Mocked Delegates
Consider this delegate:
public delegate int ParseString(string value);
To mock it:
var mock = new Mock<ParseString>();
mock.Setup(p => p(It.IsAny<string>()))
.Returns(42);