will will - 1 month ago 13
C# Question

Verifying a method call in a base class that takes a delegate parameter using Moq

I am trying to test that a method is called, and that method exists in a base class of the class under test.

When I run the below example with a simple string parameter it works but when there is a delegate parameter the test fails.

I created the below sample to demonstrate the problem. If you take out the delegate parameter in

SomeMethod
and in the test, the test will pass.

Failing Code:



public abstract class BaseClass
{
public virtual void SomeMethod(string someString, Func<bool> function)
{
//do something
}
}

public class DerivedClass : BaseClass
{
public void DoSomething()
{
SomeMethod("foo", () => true);
}
}

[TestClass]
public class Tests
{
[TestMethod]
public void TestMethod1()
{
var test = new Mock<DerivedClass>();
test.Object.DoSomething();
test.Verify(x => x.SomeMethod("foo", () => true), Times.AtLeastOnce);
}
}


Passing Code:



public abstract class BaseClass
{
public virtual void SomeMethod(string someString)
{
//do something
}
}

public class DerivedClass : BaseClass
{
public void DoSomething()
{
SomeMethod("foo");
}
}

[TestClass]
public class Tests
{
[TestMethod]
public void TestMethod1()
{
var test = new Mock<DerivedClass>();
test.Object.DoSomething();
test.Verify(x => x.SomeMethod("foo"), Times.AtLeastOnce);
}
}


Error message for failing test:



Expected invocation on the mock at least once, but was never performed: x => x.SomeMethod("foo", () => True)
No setups configured.

Performed invocations:
BaseClass.SomeMethod("foo", System.Func1[System.Boolean])`


Whole error message:

Test method UnitTestProject1.Tests.TestMethod1 threw exception:
Moq.MockException:
Expected invocation on the mock at least once, but was never performed: x => x.SomeMethod("foo", () => True)
No setups configured.

Performed invocations:
BaseClass.SomeMethod("foo", System.Func`1[System.Boolean])
at Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable`1 setups, IEnumerable`1 actualCalls, Expression expression, Times times, Int32 callCount)
at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times)
at Moq.Mock.Verify(Mock`1 mock, Expression`1 expression, Times times, String failMessage)
at Moq.Mock`1.Verify(Expression`1 expression, Times times)
at Moq.Mock`1.Verify(Expression`1 expression, Func`1 times)
at UnitTestProject1.Tests.TestMethod1() in UnitTest1.cs: line 16

Answer

If I change the test to following it passes. See I changed () => true to It.IsAny<Func<bool>>() which means it can be called with any Func. Do you care if its () => true?

var test = new Mock<DerivedClass>();
test.Object.DoSomething();
test.Verify(x => x.SomeMethod("foo", It.IsAny<Func<bool>>()), Times.AtLeastOnce);