In this article, we are going to see how to determine if a method is called during test execution. To do that, we are going to use Moq and its verification APIs.
Let’s start by exploring the most common approaches.
Determine If a Method is Called by Using Verify(), Verifiable() or VerifyAll()
Moq proposes three primary ways we should use to determine whether we have called a method or not. All of them have some pros and cons, so let’s learn when and how to use each of them.
Verify()
The first one is based on Mock.Verify()
, that accepts a lambda containing the method we want to verify:
var myClass = new Mock<MyClass>(); myClass.Object.MyMethod(); myClass.Verify(d => d.MyMethod());
This is probably the clearest approach because we can immediately see the method we want to verify. The upside is that it is fully compliant with the AAA pattern, which recommends putting all the assertions at the end of the test body. The downside is that you need to call Setup()
and Verify()
on all the methods you want to verify. These repetitions become annoying, and that’s why, in this case, we should use something else.
Doing many verifications in the same test is generally an antipattern because the test body should be as small as possible. For this reason, this approach is the most commonly used, but the other ones can be very useful too in some contexts.
Verifiable()
We can also chain the setup and verification parts in a single line:
var myClass = new Mock<MyClass>(); myClass.Setup(c => c.MyMethod()).Verifiable(); myClass.Object.MyMethod(); myClass.Verify();
After each setup phase, we can call Verifiable()
, that marks the mocked method as verifiable. Eventually, myClass.Verify()
checks whether we have called all the marked methods with the parameters provided in the setup phase.
The first downside is that the verifiable assertions are scattered throughout the arrange phase of each test, instead of being in the assert phase only. The second downside is that this approach is not as flexible as the first one because we cannot control how many times we can call a certain method.
VerifyAll()
This last option is probably the simplest one among the three, but it also has the riskiest:
var myClass = new Mock<MyClass>(); myClass.Setup(c => c.MyMethod()); myClass.Object.MyMethod(); myClass.VerifyAll();
VerifyAll()
marks all the mocks we have called Setup()
on as to-verify. At the first glance, it seems a very elegant approach because we usually want the methods we mock to be called during the test execution. However, there is always the risk that we’re going to verify more method calls than we expected.
For example, we could initialize some mocks in the test initialization method (the one decorated with [TestInitialize]
). In some tests, those mocks might be unnecessary, but, because of the VerifyAll()
call, we are forced to call them anyway.
We should not abuse this approach because it could lead to frequent refactoring, especially when we mock non-public methods. Let’s go back to the first approach because we have left some issues hanging.
More Powerful Verifications With Times
The Verify()
method has some interesting overloads we can utilize to achieve more flexibility. By default, this method verifies whether we have called the target method at least once. We can create more complex assertions by specifying a second parameter, after the lambda expression.
For example, we may want to assert that we have called a method exactly once:
myClass.Verify(d => d.PublicMethod(), Times.Once);
Or that is never called it:
myClass.Verify(d => d.PublicMethod(), Times.Never);
Or even a specific number of times, three in this case:
myClass.Verify(d => d.PublicMethod(), Times.Exactly(3));
The Times
struct offers other methods that we are not going to cover here because it’s very easy to understand.
This is one of the upsides that make the first approach very flexible and the one we should typically prefer.
Now that we have explored the options we have, let’s see them in action in real-life scenarios.
Using Verify() For Methods With Different Access Modifiers
Moq is built upon the DynamicProxy
library of the Castle project, which allows Moq to create proxies from abstract or concrete classes. A heavy constraint of this library is that a proxied method must be overridable. For this reason, the sample class we will start from has several virtual methods:
public class MyClass { public void CallingPublicMethod() { PublicMethod(); } virtual public void PublicMethod() {} public void CallingProtectedMethod() { ProtectedMethod(); } virtual protected void ProtectedMethod() {} public void CallingInternalMethod() { InternalMethod(); } virtual internal void InternalMethod() {} }
Let’s begin with the simplest verification.
Public Method Verification
Public methods don’t require any effort because we can use Verify()
in the same way we did in the previous examples:
var myClass = new Mock<MyClass>(); myClass.Object.CallingPublicMethod(); myClass.Verify(d => d.PublicMethod());
At this point, we should be familiar with this structure, so let’s move on to the next access modifier.
Protected Method Verification
As for the protected methods, it’s a bit more complex:
var myClass = new Mock<MyClass>(); myClass.Object.CallingProtectedMethod(); myClass.Protected().Verify("ProtectedMethod", Times.Once());
The Mock<T>
object must be transformed to an IProtectedMock<T>
object, by calling Protected()
on it.
This new mock can now access all the protected methods, but the Verify()
signature is also a bit different. Instead of a lambda expression, we now have to provide the method name string and we need to specify the Times
parameter as well.
Internal Method Verification
Regarding internal method verification, the easiest way to do that is to change the .csproj file of the application assembly. It has to include this item group, as a child of the <Project>
root tag:
<ItemGroup> <InternalsVisibleTo Include="YourTestAssemblyName" /> <InternalsVisibleTo Include="DynamicProxyGenAssembly2" /> </ItemGroup>
The InternalVisibleTo
tag is self-explanatory, but why do we need to specify it for DynamicProxyGenAssembly2
? Because runtime-generated mocked classes, which are proxies, cannot be put in an already loaded assembly. For this reason, they are all added to the DynamicProxyGenAssembly2
, which is a temporary assembly.
Now that we have made these changes, we can access internal methods from the test assembly simply using the dot notation.
So far, we have covered only concrete methods verification, but how about the abstract/interface methods?
How to Verify Abstract/Interface Methods?
Abstract and interface methods are overridable by definition, so we do not have to worry about the virtual
modifier. Let’s create an interface:
public interface IDependency { void DepInterfacePublicMethod(); }
And a class that depends on it:
public class MyClass { private IDependency _idep; public MyClass(IDependency idep) { _idep = idep; } public void CallingInterfaceDependencyPublicMethod() { _idep.DepInterfacePublicMethod(); } }
If we want to test if we’ve called the mocked interface method, we can mock the dependency directly:
var depMock = new Mock<IDependency>(); var myClass = new MyClass(depMock.Object); myClass.CallingInterfaceDependencyPublicMethod(); depMock.Verify(d => d.DepInterfacePublicMethod());
Let’s try with an abstract class as well:
public abstract class AbstractDependency { abstract public void DepAbstractPublicMethod(); }
And another version of MyClass
that accepts an AbstractDependency
in its constructor:
public class MyClass { private AbstractDependency _abstractDep; public MyClass(AbstractDependency abstractDep) { _abstractDep = abstractDep; } public void CallingAbstractDependencyPublicMethod() { _abstractDep.DepAbstractPublicMethod(); } }
Here is how we can test if we have called DepAbstractPublicMethod()
:
var depMock = new Mock<AbstractDependency>(); var myClass = new MyClass(depMock.Object); myClass.CallingAbstractDependencyPublicMethod(); depMock.Verify(d => d.DepAbstractPublicMethod());
The ability of Moq to mock an interface or an abstract class turns out to be very useful in this case. Especially during unit testing, injecting abstract dependencies allows us to easily integrate the verification APIs.
Let’s sum it all up.
Conclusions
Verification APIs are very flexible but we may need to do some extra work to verify protected
or internal
methods. We should never forget that verifying a non-public method is still very risky because the implementation could change in the future.
Instead, it’s better to verify that public methods of our dependencies are called correctly during the test flow. This is typically safer because only a major release can affect the public interfaces it exposes.