There are many mocking frameworks in the .NET world. Probably, the best known is Rhino Mocks. I used it and I found it a little tricky. I had to browse its documentation many times to find out how to do something. Recently, through some technical reading, I have found another mocking framework called Moq. What attracted my attention to it was really simple and intuitive api.
Introduction
Moq is pronounced as “Mock-you” or simple “Mock”. The current version is 3.1. 0. It supports .NET 3.5, so you can use Linq and lambda expressions. All information you need to start working with it can be found on its quick start page.
In this post, I would like to shortly present Moq’s most useful features. All examples are taken from Moq quick start.
Creating a mock
Imagine that we have an interface IFoo.
public interface IFoo { string Name { get; set; } string Execute(string arg); }
Imagine that we have a client of this interface and we want to test it. So, we need a mock. We use the “new” operator and type we want to mock to create it.
var mock = new Mock<IFoo>();
Now, we need a reference to mocked type. We get it in the following way:
IFoo foo = mock.Object;
Then, we pass it to the client.
Setting up method expectations
It’s time for setting up expectations. We use mock’s method Setup().
mock.Setup(foo => foo.Execute("value1")).Returns("response1"); mock.Setup(foo => foo.Execute("value2")).Returns("response2");
This will cause mock to return “response1” for “value1” and “response2” for “value2”. We might also setup expectation for any value of argument.
mock.Setup(x => x.Execute(It.IsAny<string>))) .Returns((string s) => s.ToLower());
To specify arguments more precisely, we might use methods of “It” class such as IsInRange(), IsRegex(), Is(). This is really powerful. Another interesting thing you can see here is lazy evaluation of return value and access to passed argument.
What is more, it is possible to setup exceptions to be thrown.
mock.Setup(foo => foo.Execute("reset")) .Throws<InvalidOperationException>(); mock.Setup(foo => foo.Execute("")) .Throws(new ArgumentException("command"));
Call to foo.Execute with argument “reset” will result in throwing an InvalidOperationException by mock, call with argument “” will cause an ArgumentException to be thrown.
Last thing I want to show in this section is use of callbacks.
mock.Setup(foo => foo.Execute("ping")) .Callback(() => Console.WriteLine("Before returns")) .Returns(true) .Callback(() => Console.WriteLine("After returns"));
Callback() might be used before Returns() or after it or in both places as in the example above.
Setting up properties
Setting up expectations for property is also very straightforward.
mock.Setup(foo => foo.Name).Returns("bar");
Now, foo.Name returns value “bar”. We can also expect a setter invocation.
mock.SetupSet(foo => foo.Name = "foo");
If we want a property value to be tracked, we might use the snippet below.
mock.SetupProperty(f => f.Name);
This will cause storing value set to property, so the code below will pass.
mock.SetupProperty(f => f.Name, "foo"); IFoo foo = mock.Object; Assert.Equal("foo", foo.Name); //inital value == "foo" foo.Name = "bar"; Assert.Equal("bar", foo.Name);//now value == "bar"
We set up expectations. Now, time for verification.
Verifying calls
Many times we need to check if a method was called or an event was fired. Below, in the first line we are verifying if there was a call to Execute with argument “ping”. In the second line we test if call to Execute with any string argument occurred.
mock.Verify(foo => foo.Execute("ping")); mock.Verify(foo => foo.Execute(It.IsAny<string>()));
Sometimes, we might want to check how many times the method was called. We use “Times” class for this purpose.
mock.Verify(foo => foo.Execute("ping"), Times.Never()); mock.Verify(foo => foo.Execute("ping"), Times.AtLeastOnce());
We also might want to verify if a property was used.
mock.VerifyGet(f => f.Name); mock.VerifySet(foo => foo.Name);
Strict mocks, loose mocks
By default, every mock we create behaves like “loose” mock. It means that every call to property or method, which was not set up, results in returning the default value. If we want to test it more precisely, we can use “strict” behavior. In this case, every unexpected call will cause an exception to be thrown.
var mock = new Mock<IFoo>(MockBehavior.Strict);
Summary
I made only a short preview of Moq possibilities. You can find further information on Moq homepage. I would recommend reading the quick start, which I think provides all information necessary to start working with the framework.
Moq in my opinion is extremely developer friendly. It has really nice syntax which helps to produce clean and readable code. Surely, I will try it in real development.