I have a third party interface which I want to mock its methods. To make my purpose clear consider the following IFoo interface which has a generic method like M2. One of M2 arguments is of type Func
public interface IFoo
{
bool M1<T>();
bool M2<T>(T arg, Func<T, string> func);
}
If I set up the M2 method as:
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.M2(It.IsAny<It.IsAnyType>(),It.IsAny<Func<It.IsAnyType, string>>())).Returns(true);
mock.Object.M2("arg1", s => s);
mock.Verify(foo => foo.M2(It.IsAny<It.IsAnyType>(), It.IsAny<Func<It.IsAnyType, string>>()));
then verify will fail. But if it is set up and verified with a specific type like string then it works:
mock.Setup(foo => foo.M2(It.IsAny<string>(), It.IsAny<Func<string, string>>())).Returns(true);
mock.Object.M2("arg1", s => s);
mock.Verify(foo => foo.M2(It.IsAny<string>(), It.IsAny<Func<string, string>>()));
The problem is that the actual type of T passed to my Mock is an internal class defined in that third party library. So I can't set up and verify with a specific type like the above-mentioned one.
Am I missing something in my first set up or verify or it is a well-known issue which has not been addressed yet?
I am using moq 4.13.1 and my test project is .Net Core 3.1
It.IsAny<Func<It.IsAnyType, string>>
That won't work (yet). Using type matchers like It.IsAnyType nested inside some other type isn't implemented yet, see #919.
Since you don't seem to care about what was passed in, I'd just use It.IsAny<object> instead.
I tried It.IsAny<object> before I posted this issue and it didn't work.
Hmm, perhaps (Func<It.IsAnyType, string>)It.IsAny<object>() then?
(Sorry, I can't try this at the moment so it's just a guess, but it might work. The type cast will be ignored at runtime but should make the compiler's type checker happy; the It.IsAny<object>() bit is what Moq will match against at runtime.)
Thanks, it solved the problem
Most helpful comment
Hmm, perhaps
(Func<It.IsAnyType, string>)It.IsAny<object>()then?(Sorry, I can't try this at the moment so it's just a guess, but it might work. The type cast will be ignored at runtime but should make the compiler's type checker happy; the
It.IsAny<object>()bit is what Moq will match against at runtime.)