-
-
Notifications
You must be signed in to change notification settings - Fork 798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Verify does not distinguish between a type and its implemented type in generic methods #660
Comments
Hi @LizzyBradley and thank you for reporting this. On the surface, this looks like a bug. But I'm not sure that it actually is one. I'll post an example demonstrating why below, but let me first take a step back and describe the greater context of this issue. We currently have two issues that are about the same general topic of how Moq should match method signatures against expectations. Interestingly, the two issues ask for opposing solutions:
I'm not sure which type comparison (exact equality vs. assignment compatibility) for which part of a method signature (return type vs. generic type parameter vs. regular parameter) in which situation (setup vs. verification) is the right combination that everyone will be happy with. I suspect that no matter whatever kind of signature matching we decide on, we're going to break someone else's code. (Am I wrong in suspecting that there's no perfect solution to all of this? If someone has the answer—possibly derived from ECMA-335—that also won't break preexisting user code—or at least not too badly—I'd be happy to hear about it.) Btw., the above scenario starts to look less wrong once the mocked method actually takes a parameter of the generic type parameter. Take this slightly altered example, where I just renamed public class Animal { }
public class Horse : Animal { }
public interface IFeeder
{
void Feed<T>(T x) { }
}
var mock = new Mock<IFeeder>();
mock.Object.Feed(new Horse());
mock.Verify(m => m.Feed(It.IsAny<Animal>()), Times.Never()); If you're anything like me, you'd probably expect verification failure to happen here, since we did feed an animal, after all. |
@LizzyBradley - given the above feedback, how do you think we should proceed with this issue? (If there's no further response, I'll close this issue in about 3-4 days' time.) |
@Lizzy-Gallagher - In Moq 4.13.0, you can now use type matchers to get your test to pass. First, define a type matcher that matches an exact type: [TypeMatcher]
public class IsExactType<T> : ITypeMatcher
{
public bool Matches(Type typeArgument) => typeArgument == typeof(T);
} Then change your call to -mock.Verify(m => m.DoSomething< Default >(), Times.Never()); // Fails, it is called once
+mock.Verify(m => m.DoSomething<IsExactType<Default>>(), Times.Never()); // Passes |
Normally, Verify usually can distinguish between types for generic method. However, when a type implements another, Verify logs that both types have been used. In the below example (using Moq 4.9), the line with Verify fails because it thinks that the method has been called with the type argument Default.
The text was updated successfully, but these errors were encountered: