From 1544e61be362f03e4aa0fa55bb3a47a05a6c04fe Mon Sep 17 00:00:00 2001 From: wojtek Date: Mon, 6 Aug 2012 17:40:20 +0100 Subject: [PATCH 1/3] corrected Verify method behavior for generic methods calls like: public interface IBaz { void Call(T param) where T:IBazParam; } public void MatchesDerivedTypesForGenericTypes() { var mock = new Mock(); mock.Object.Call(new BazParam()); mock.Object.Call(new BazParam2()); mock.Verify(foo => foo.Call(It.IsAny()), Times.Exactly(2)); } --- Source/MethodCall.cs | 21 ++++++++++++++++++--- UnitTests/VerifyFixture.cs | 26 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/Source/MethodCall.cs b/Source/MethodCall.cs index 06a251df6..b21b11b35 100644 --- a/Source/MethodCall.cs +++ b/Source/MethodCall.cs @@ -81,7 +81,20 @@ public IVerifies Raises(Action eventExpression, params object[] args) } } - internal partial class MethodCall : IProxyCall, ICallbackResult, IVerifies, IThrowsResult + internal class TypeEqualityComaprer : IEqualityComparer + { + public bool Equals(Type x, Type y) + { + return y.IsAssignableFrom(x); + } + + public int GetHashCode(Type obj) + { + return obj.GetHashCode(); + } + } + + internal partial class MethodCall : IProxyCall, ICallbackResult, IVerifies, IThrowsResult { // Internal for AsMockExtensions private Expression originalExpression; @@ -95,8 +108,9 @@ internal partial class MethodCall : IProxyCall, ICallbackResult, IVerifies, IThr private int? expectedCallCount = null; protected Func condition; private List> outValues = new List>(); + private static readonly IEqualityComparer typesComparer = new TypeEqualityComaprer(); - public MethodCall(Mock mock, Func condition, Expression originalExpression, MethodInfo method, params Expression[] arguments) + public MethodCall(Mock mock, Func condition, Expression originalExpression, MethodInfo method, params Expression[] arguments) { this.Mock = mock; this.condition = condition; @@ -363,12 +377,13 @@ private bool IsEqualMethodOrOverride(ICallContext call) { if (!this.Method.Name.Equals(call.Method.Name, StringComparison.Ordinal) || this.Method.ReturnType != call.Method.ReturnType || + !call.Method.IsGenericMethod && this.Method.IsGenericMethod && !call.Method.GetParameterTypes().SequenceEqual(this.Method.GetParameterTypes())) { return false; } - if (Method.IsGenericMethod && !call.Method.GetGenericArguments().SequenceEqual(Method.GetGenericArguments())) + if (Method.IsGenericMethod && !call.Method.GetGenericArguments().SequenceEqual(Method.GetGenericArguments(),typesComparer)) { return false; } diff --git a/UnitTests/VerifyFixture.cs b/UnitTests/VerifyFixture.cs index 10365f597..7c3c29f04 100644 --- a/UnitTests/VerifyFixture.cs +++ b/UnitTests/VerifyFixture.cs @@ -866,6 +866,15 @@ public void IncludesMessageAboutNoActualCallsInFailureMessage() Assert.Contains(Environment.NewLine + "No invocations performed.", mex.Message); } + [Fact] + public void MatchesDerivedTypesForGenericTypes() + { + var mock = new Mock(); + mock.Object.Call(new BazParam()); + mock.Object.Call(new BazParam2()); + + mock.Verify(foo => foo.Call(It.IsAny()), Times.Exactly(2)); + } public interface IBar { @@ -882,6 +891,23 @@ public interface IFoo void Submit(); string Execute(string command); } + + public interface IBazParam + { + } + + public interface IBaz + { + void Call(T param) where T:IBazParam; + } + + public class BazParam:IBazParam + { + } + + public class BazParam2:BazParam + { + } } } From 9adec25e0bf9109c6cce3b8e77286afffda9ff35 Mon Sep 17 00:00:00 2001 From: wojtek Date: Mon, 6 Aug 2012 17:56:07 +0100 Subject: [PATCH 2/3] small correction in MethodCall.IsEqualMethodOrOverride() --- Source/MethodCall.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/MethodCall.cs b/Source/MethodCall.cs index b21b11b35..174e491a8 100644 --- a/Source/MethodCall.cs +++ b/Source/MethodCall.cs @@ -377,7 +377,7 @@ private bool IsEqualMethodOrOverride(ICallContext call) { if (!this.Method.Name.Equals(call.Method.Name, StringComparison.Ordinal) || this.Method.ReturnType != call.Method.ReturnType || - !call.Method.IsGenericMethod && this.Method.IsGenericMethod && + !this.Method.IsGenericMethod && !call.Method.GetParameterTypes().SequenceEqual(this.Method.GetParameterTypes())) { return false; From c8687b8910733261f80873ad36d3881edc40ad68 Mon Sep 17 00:00:00 2001 From: wojtek Date: Thu, 30 Aug 2012 10:01:24 +0100 Subject: [PATCH 3/3] corrected small typo --- Source/MethodCall.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/MethodCall.cs b/Source/MethodCall.cs index 174e491a8..f0eac0d89 100644 --- a/Source/MethodCall.cs +++ b/Source/MethodCall.cs @@ -81,7 +81,7 @@ public IVerifies Raises(Action eventExpression, params object[] args) } } - internal class TypeEqualityComaprer : IEqualityComparer + internal class TypeEqualityComparer : IEqualityComparer { public bool Equals(Type x, Type y) { @@ -108,7 +108,7 @@ internal partial class MethodCall : IProxyCall, ICallbackResult, IVerifies, IThr private int? expectedCallCount = null; protected Func condition; private List> outValues = new List>(); - private static readonly IEqualityComparer typesComparer = new TypeEqualityComaprer(); + private static readonly IEqualityComparer typesComparer = new TypeEqualityComparer(); public MethodCall(Mock mock, Func condition, Expression originalExpression, MethodInfo method, params Expression[] arguments) {