Moq is only able to mock out methods which are virtual (or provide mock implementations for interfaces). If you try a Setup
or Verify
on a non-virtual member, you'll get the error
Invalid verify on a non-virtual member: m => m.TestMethod2()
In your case, you would need to change TestMethod2
to virtual, i.e.
public virtual void TestMethod2()
Which can then be tested:
var aMock = new Mock<A>();
aMock.Object.TestMethod();
aMock.Verify(m => m.TestMethod2(), Times.Once);
As you've suggested, testing whether a class calls methods internal to itself is a smell, indication that you're either
- Testing internal implementation detail (e.g. if
TestMethod2()
was private, it's none of our business to even know about it).
- Or, an indication that the Class / System under test is in need of refactoring into multiple classes, which should be loosely coupled, and hence can be isolated and better testable.
Note
- You can't
Verify
a call before you've invoked the method on the SUT that you want to test, i.e. move the Verify
to after the invocation of .TestMethod()
as I've done.
- Although you could change your code to use the
Setup
+ VerifyAll
approach to testing, i.e. ensuring that everything you've setup is actually invoked:
aMock.Setup(m => m.TestMethod2());
aMock.Object.TestMethod();
aMock.VerifyAll();
There is however debate around whether the usage of VerifyAll
violates AAA
principals (since you're also in effect specifying the Verify
criteria in the Arrange
piece), and I've also found that this approach makes it impossible to refactor and DRY up Mock setups in large scale tests, and you also lose some of the finer level of checking (e.g. Times.Once
).