diff --git a/src/Moq/IInvocation.cs b/src/Moq/IInvocation.cs
index c2982b920..9104d41ae 100644
--- a/src/Moq/IInvocation.cs
+++ b/src/Moq/IInvocation.cs
@@ -41,5 +41,10 @@ public interface IInvocation
/// Optional exception if the method invocation results in an exception being thrown.
///
Exception Exception { get; }
+
+ ///
+ /// A number representing the order of this invocation in time with respect to all other invocations
+ ///
+ long SequenceNumber { get; }
}
}
\ No newline at end of file
diff --git a/src/Moq/IVerifyResult.cs b/src/Moq/IVerifyResult.cs
new file mode 100644
index 000000000..753176278
--- /dev/null
+++ b/src/Moq/IVerifyResult.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Moq
+{
+ ///
+ /// A collection of invocations verified by a call to mock.Verify() or one of its variations
+ ///
+ /// The type being mocked and verified
+ public interface IVerifyResult : IReadOnlyList where T: class
+ {
+ ///
+ /// The mock that was verified
+ ///
+ Mock Mock { get; }
+ }
+}
diff --git a/src/Moq/Invocation.cs b/src/Moq/Invocation.cs
index 9b8a237f2..ba25eec14 100644
--- a/src/Moq/Invocation.cs
+++ b/src/Moq/Invocation.cs
@@ -6,7 +6,7 @@
using System.Diagnostics;
using System.Reflection;
using System.Text;
-
+using System.Threading;
using Moq.Async;
namespace Moq
@@ -20,6 +20,8 @@ abstract class Invocation : IInvocation
object result;
Setup matchingSetup;
bool verified;
+ long sequenceNumber;
+ static long globalSequenceNumber = 0;//ONLY access with Interlocked.Increment()
///
/// Initializes a new instance of the class.
@@ -36,8 +38,11 @@ protected Invocation(Type proxyType, MethodInfo method, params object[] argument
this.arguments = arguments;
this.method = method;
this.proxyType = proxyType;
+ this.sequenceNumber = Interlocked.Increment(ref globalSequenceNumber);
}
+ public long SequenceNumber => this.sequenceNumber;
+
///
/// Gets the method of the invocation.
///
diff --git a/src/Moq/Mock.cs b/src/Moq/Mock.cs
index 958494f17..a782288c9 100644
--- a/src/Moq/Mock.cs
+++ b/src/Moq/Mock.cs
@@ -313,7 +313,7 @@ internal void Verify(Func predicate, HashSet verifiedMocks)
}
}
- internal static void Verify(Mock mock, LambdaExpression expression, Times times, string failMessage)
+ internal static IEnumerable Verify(Mock mock, LambdaExpression expression, Times times, string failMessage)
{
Guard.NotNull(times, nameof(times));
@@ -326,6 +326,7 @@ internal static void Verify(Mock mock, LambdaExpression expression, Times times,
part.SetupEvaluatedSuccessfully(invocation);
invocation.MarkAsVerified();
}
+ return invocationsToBeMarkedAsVerified.Select(pair => (IInvocation)pair.Item1);
}
else
{
@@ -333,7 +334,7 @@ internal static void Verify(Mock mock, LambdaExpression expression, Times times,
}
}
- internal static void VerifyGet(Mock mock, LambdaExpression expression, Times times, string failMessage)
+ internal static IEnumerable VerifyGet(Mock mock, LambdaExpression expression, Times times, string failMessage)
{
Guard.NotNull(expression, nameof(expression));
@@ -343,31 +344,31 @@ internal static void VerifyGet(Mock mock, LambdaExpression expression, Times tim
Guard.CanRead(property);
}
- Mock.Verify(mock, expression, times, failMessage);
+ return Mock.Verify(mock, expression, times, failMessage);
}
- internal static void VerifySet(Mock mock, LambdaExpression expression, Times times, string failMessage)
+ internal static IEnumerable VerifySet(Mock mock, LambdaExpression expression, Times times, string failMessage)
{
Guard.NotNull(expression, nameof(expression));
Guard.IsAssignmentToPropertyOrIndexer(expression, nameof(expression));
- Mock.Verify(mock, expression, times, failMessage);
+ return Mock.Verify(mock, expression, times, failMessage);
}
- internal static void VerifyAdd(Mock mock, LambdaExpression expression, Times times, string failMessage)
+ internal static IEnumerable VerifyAdd(Mock mock, LambdaExpression expression, Times times, string failMessage)
{
Guard.NotNull(expression, nameof(expression));
Guard.IsEventAdd(expression, nameof(expression));
- Mock.Verify(mock, expression, times, failMessage);
+ return Mock.Verify(mock, expression, times, failMessage);
}
- internal static void VerifyRemove(Mock mock, LambdaExpression expression, Times times, string failMessage)
+ internal static IEnumerable VerifyRemove(Mock mock, LambdaExpression expression, Times times, string failMessage)
{
Guard.NotNull(expression, nameof(expression));
Guard.IsEventRemove(expression, nameof(expression));
- Mock.Verify(mock, expression, times, failMessage);
+ return Mock.Verify(mock, expression, times, failMessage);
}
internal static void VerifyNoOtherCalls(Mock mock)
diff --git a/src/Moq/Mock`1.cs b/src/Moq/Mock`1.cs
index d9e697875..77f4ba4bf 100644
--- a/src/Moq/Mock`1.cs
+++ b/src/Moq/Mock`1.cs
@@ -705,9 +705,10 @@ public ISetupConditionResult When(Func condition)
/// mock.Verify(proc => proc.Execute("ping"));
///
///
- public void Verify(Expression> expression)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression)
{
- Mock.Verify(this, expression, Times.AtLeastOnce(), null);
+ return new VerifyResult(this, Mock.Verify(this, expression, Times.AtLeastOnce(), null));
}
///
@@ -719,9 +720,10 @@ public void Verify(Expression> expression)
///
/// The invocation was not called the number of times specified by .
///
- public void Verify(Expression> expression, Times times)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, Times times)
{
- Mock.Verify(this, expression, times, null);
+ return new VerifyResult(this, Mock.Verify(this, expression, times, null));
}
///
@@ -733,9 +735,10 @@ public void Verify(Expression> expression, Times times)
///
/// The invocation was not called the number of times specified by .
///
- public void Verify(Expression> expression, Func times)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, Func times)
{
- Verify(expression, times());
+ return Verify(expression, times());
}
///
@@ -746,9 +749,10 @@ public void Verify(Expression> expression, Func times)
/// Expression to verify.
/// Message to show if verification fails.
/// The invocation was not performed on the mock.
- public void Verify(Expression> expression, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, string failMessage)
{
- Mock.Verify(this, expression, Times.AtLeastOnce(), failMessage);
+ return new VerifyResult(this, Mock.Verify(this, expression, Times.AtLeastOnce(), failMessage));
}
///
@@ -762,9 +766,10 @@ public void Verify(Expression> expression, string failMessage)
///
/// The invocation was not called the number of times specified by .
///
- public void Verify(Expression> expression, Times times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, Times times, string failMessage)
{
- Mock.Verify(this, expression, times, failMessage);
+ return new VerifyResult(this, Mock.Verify(this, expression, times, failMessage));
}
///
@@ -778,9 +783,10 @@ public void Verify(Expression> expression, Times times, string failMes
///
/// The invocation was not called the number of times specified by .
///
- public void Verify(Expression> expression, Func times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, Func times, string failMessage)
{
- Mock.Verify(this, expression, times(), failMessage);
+ return new VerifyResult(this, Mock.Verify(this, expression, times(), failMessage));
}
///
@@ -802,9 +808,10 @@ public void Verify(Expression> expression, Func times, string f
/// mock.Verify(warehouse => warehouse.HasInventory(TALISKER, 50));
///
///
- public void Verify(Expression> expression)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression)
{
- Mock.Verify(this, expression, Times.AtLeastOnce(), null);
+ return new VerifyResult(this, Mock.Verify(this, expression, Times.AtLeastOnce(), null));
}
///
@@ -817,9 +824,10 @@ public void Verify(Expression> expression)
///
/// The invocation was not called the number of times specified by .
///
- public void Verify(Expression> expression, Times times)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, Times times)
{
- Mock.Verify(this, expression, times, null);
+ return new VerifyResult(this, Mock.Verify(this, expression, times, null));
}
///
@@ -832,9 +840,10 @@ public void Verify(Expression> expression, Times times
///
/// The invocation was not called the number of times specified by .
///
- public void Verify(Expression> expression, Func times)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, Func times)
{
- Mock.Verify(this, expression, times(), null);
+ return new VerifyResult(this, Mock.Verify(this, expression, times(), null));
}
///
@@ -848,9 +857,10 @@ public void Verify(Expression> expression, Func
///
/// The invocation was not called the number times specified by .
///
- public void Verify(Expression> expression, Func times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, Func times, string failMessage)
{
- Mock.Verify(this, expression, times(), failMessage);
+ return new VerifyResult(this, Mock.Verify(this, expression, times(), failMessage));
}
///
@@ -874,9 +884,10 @@ public void Verify(Expression> expression, Func
/// "When filling orders, inventory has to be checked");
///
///
- public void Verify(Expression> expression, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, string failMessage)
{
- Mock.Verify(this, expression, Times.AtLeastOnce(), failMessage);
+ return new VerifyResult(this, Mock.Verify(this, expression, Times.AtLeastOnce(), failMessage));
}
///
@@ -890,9 +901,10 @@ public void Verify(Expression> expression, string fail
///
/// The invocation was not called the number times specified by .
///
- public void Verify(Expression> expression, Times times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult Verify(Expression> expression, Times times, string failMessage)
{
- Mock.Verify(this, expression, times, failMessage);
+ return new VerifyResult(this, Mock.Verify(this, expression, times, failMessage));
}
///
@@ -912,12 +924,13 @@ public void Verify(Expression> expression, Times times
/// ... // exercise mock
///
/// // Will throw if the test code didn't retrieve the IsClosed property.
- /// mock.VerifyGet(warehouse => warehouse.IsClosed);
+ /// new VerifyResult(this, mock.VerifyGet(warehouse => warehouse.IsClosed));
///
///
- public void VerifyGet(Expression> expression)
+ /// A list of matching invocations
+ public IVerifyResult VerifyGet(Expression> expression)
{
- Mock.VerifyGet(this, expression, Times.AtLeastOnce(), null);
+ return new VerifyResult(this, Mock.VerifyGet(this, expression, Times.AtLeastOnce(), null));
}
///
@@ -931,9 +944,10 @@ public void VerifyGet(Expression> expression)
///
/// The invocation was not called the number times specified by .
///
- public void VerifyGet(Expression> expression, Times times)
+ /// A list of matching invocations
+ public IVerifyResult VerifyGet(Expression> expression, Times times)
{
- Mock.VerifyGet(this, expression, times, null);
+ return new VerifyResult(this, Mock.VerifyGet(this, expression, times, null));
}
///
@@ -947,9 +961,10 @@ public void VerifyGet(Expression> expression, Time
///
/// The invocation was not called the number times specified by .
///
- public void VerifyGet(Expression> expression, Func times)
+ /// A list of matching invocations
+ public IVerifyResult VerifyGet(Expression> expression, Func times)
{
- VerifyGet(this, expression, times(), null);
+ return new VerifyResult(this, VerifyGet(this, expression, times(), null));
}
///
@@ -961,9 +976,10 @@ public void VerifyGet(Expression> expression, Func
/// Type of the property to verify. Typically omitted as it can be inferred from the expression's return type.
///
/// The invocation was not performed on the mock.
- public void VerifyGet(Expression> expression, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifyGet(Expression> expression, string failMessage)
{
- Mock.VerifyGet(this, expression, Times.AtLeastOnce(), failMessage);
+ return new VerifyResult(this, Mock.VerifyGet(this, expression, Times.AtLeastOnce(), failMessage));
}
///
@@ -978,9 +994,10 @@ public void VerifyGet(Expression> expression, stri
///
/// The invocation was not called the number times specified by .
///
- public void VerifyGet(Expression> expression, Times times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifyGet(Expression> expression, Times times, string failMessage)
{
- Mock.VerifyGet(this, expression, times, failMessage);
+ return new VerifyResult(this, Mock.VerifyGet(this, expression, times, failMessage));
}
///
@@ -995,9 +1012,10 @@ public void VerifyGet(Expression> expression, Time
///
/// The invocation was not called the number times specified by .
///
- public void VerifyGet(Expression> expression, Func times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifyGet(Expression> expression, Func times, string failMessage)
{
- VerifyGet(this, expression, times(), failMessage);
+ return new VerifyResult(this, VerifyGet(this, expression, times(), failMessage));
}
///
@@ -1014,15 +1032,16 @@ public void VerifyGet(Expression> expression, Func
/// ... // exercise mock
///
/// // Will throw if the test code didn't set the IsClosed property.
- /// mock.VerifySet(warehouse => warehouse.IsClosed = true);
+ /// new VerifyResult(this, mock.VerifySet(warehouse => warehouse.IsClosed = true));
///
///
- public void VerifySet(Action setterExpression)
+ /// A list of matching invocations
+ public IVerifyResult VerifySet(Action setterExpression)
{
Guard.NotNull(setterExpression, nameof(setterExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(setterExpression, this.ConstructorArguments);
- Mock.VerifySet(this, expression, Times.AtLeastOnce(), null);
+ return new VerifyResult(this, Mock.VerifySet(this, expression, Times.AtLeastOnce(), null));
}
///
@@ -1033,12 +1052,13 @@ public void VerifySet(Action setterExpression)
///
/// The invocation was not called the number of times specified by .
///
- public void VerifySet(Action setterExpression, Times times)
+ /// A list of matching invocations
+ public IVerifyResult VerifySet(Action setterExpression, Times times)
{
Guard.NotNull(setterExpression, nameof(setterExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(setterExpression, this.ConstructorArguments);
- Mock.VerifySet(this, expression, times, null);
+ return new VerifyResult(this, Mock.VerifySet(this, expression, times, null));
}
///
@@ -1049,12 +1069,13 @@ public void VerifySet(Action setterExpression, Times times)
///
/// The invocation was not called the number of times specified by .
///
- public void VerifySet(Action setterExpression, Func times)
+ /// A list of matching invocations
+ public IVerifyResult VerifySet(Action setterExpression, Func times)
{
Guard.NotNull(setterExpression, nameof(setterExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(setterExpression, this.ConstructorArguments);
- Mock.VerifySet(this, expression, times(), null);
+ return new VerifyResult(this, Mock.VerifySet(this, expression, times(), null));
}
///
@@ -1076,12 +1097,13 @@ public void VerifySet(Action setterExpression, Func times)
/// "Warehouse should always be closed after the action");
///
///
- public void VerifySet(Action setterExpression, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifySet(Action setterExpression, string failMessage)
{
Guard.NotNull(setterExpression, nameof(setterExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(setterExpression, this.ConstructorArguments);
- Mock.VerifySet(this, expression, Times.AtLeastOnce(), failMessage);
+ return new VerifyResult(this, Mock.VerifySet(this, expression, Times.AtLeastOnce(), failMessage));
}
///
@@ -1093,12 +1115,13 @@ public void VerifySet(Action setterExpression, string failMessage)
///
/// The invocation was not called the number of times specified by .
///
- public void VerifySet(Action setterExpression, Times times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifySet(Action setterExpression, Times times, string failMessage)
{
Guard.NotNull(setterExpression, nameof(setterExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(setterExpression, this.ConstructorArguments);
- Mock.VerifySet(this, expression, times, failMessage);
+ return new VerifyResult(this, Mock.VerifySet(this, expression, times, failMessage));
}
///
@@ -1110,12 +1133,13 @@ public void VerifySet(Action setterExpression, Times times, string failMessag
///
/// The invocation was not called the number of times specified by .
///
- public void VerifySet(Action setterExpression, Func times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifySet(Action setterExpression, Func times, string failMessage)
{
Guard.NotNull(setterExpression, nameof(setterExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(setterExpression, this.ConstructorArguments);
- Mock.VerifySet(this, expression, times(), failMessage);
+ return new VerifyResult(this, Mock.VerifySet(this, expression, times(), failMessage));
}
///
@@ -1135,12 +1159,13 @@ public void VerifySet(Action setterExpression, Func times, string fail
/// mock.VerifyAdd(warehouse => warehouse.OnClosed += It.IsAny<EventHandler>());
///
///
- public void VerifyAdd(Action addExpression)
+ /// A list of matching invocations
+ public IVerifyResult VerifyAdd(Action addExpression)
{
Guard.NotNull(addExpression, nameof(addExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(addExpression, this.ConstructorArguments);
- Mock.VerifyAdd(this, expression, Times.AtLeastOnce(), null);
+ return new VerifyResult(this, Mock.VerifyAdd(this, expression, Times.AtLeastOnce(), null));
}
///
@@ -1151,12 +1176,13 @@ public void VerifyAdd(Action addExpression)
///
/// The invocation was not called the number of times specified by .
///
- public void VerifyAdd(Action addExpression, Times times)
+ /// A list of matching invocations
+ public IVerifyResult VerifyAdd(Action addExpression, Times times)
{
Guard.NotNull(addExpression, nameof(addExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(addExpression, this.ConstructorArguments);
- Mock.VerifyAdd(this, expression, times, null);
+ return new VerifyResult(this, Mock.VerifyAdd(this, expression, times, null));
}
///
@@ -1167,12 +1193,13 @@ public void VerifyAdd(Action addExpression, Times times)
///
/// The invocation was not called the number of times specified by .
///
- public void VerifyAdd(Action addExpression, Func times)
+ /// A list of matching invocations
+ public IVerifyResult VerifyAdd(Action addExpression, Func times)
{
Guard.NotNull(addExpression, nameof(addExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(addExpression, this.ConstructorArguments);
- Mock.VerifyAdd(this, expression, times(), null);
+ return new VerifyResult(this, Mock.VerifyAdd(this, expression, times(), null));
}
///
@@ -1181,12 +1208,13 @@ public void VerifyAdd(Action addExpression, Func times)
/// Expression to verify.
/// Message to show if verification fails.
/// The invocation was not performed on the mock.
- public void VerifyAdd(Action addExpression, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifyAdd(Action addExpression, string failMessage)
{
Guard.NotNull(addExpression, nameof(addExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(addExpression, this.ConstructorArguments);
- Mock.VerifyAdd(this, expression, Times.AtLeastOnce(), failMessage);
+ return new VerifyResult(this, Mock.VerifyAdd(this, expression, Times.AtLeastOnce(), failMessage));
}
///
@@ -1198,12 +1226,13 @@ public void VerifyAdd(Action addExpression, string failMessage)
///
/// The invocation was not called the number of times specified by .
///
- public void VerifyAdd(Action addExpression, Times times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifyAdd(Action addExpression, Times times, string failMessage)
{
Guard.NotNull(addExpression, nameof(addExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(addExpression, this.ConstructorArguments);
- Mock.VerifyAdd(this, expression, times, failMessage);
+ return new VerifyResult(this, Mock.VerifyAdd(this, expression, times, failMessage));
}
///
@@ -1215,12 +1244,13 @@ public void VerifyAdd(Action addExpression, Times times, string failMessage)
///
/// The invocation was not called the number of times specified by .
///
- public void VerifyAdd(Action addExpression, Func times, string failMessage)
+ /// A list of matching invocations
+ public IVerifyResult VerifyAdd(Action addExpression, Func times, string failMessage)
{
Guard.NotNull(addExpression, nameof(addExpression));
var expression = ExpressionReconstructor.Instance.ReconstructExpression(addExpression, this.ConstructorArguments);
- Mock.VerifyAdd(this, expression, times(), failMessage);
+ return new VerifyResult