From cc90a0f8234b4302114adc25a4c6ff52d5f6f0a2 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 15:59:42 +0100 Subject: [PATCH 01/23] Add Exception property to IInvocation --- src/Moq/IInvocation.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Moq/IInvocation.cs b/src/Moq/IInvocation.cs index 8324365b6..23f03dc02 100644 --- a/src/Moq/IInvocation.cs +++ b/src/Moq/IInvocation.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors. // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. +using System; using System.Collections.Generic; using System.Reflection; @@ -35,5 +36,13 @@ public interface IInvocation /// Gets the return value of the invocation. /// object ReturnValue { get; } + + /// + /// Gets the exception, thrown during the invocation. + /// + /// + /// Returns if no exception was raised. + /// + Exception Exception { get; } } } \ No newline at end of file From 2a6a5f49d46506def2e71e1dfa84c634beb656bc Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 16:13:14 +0100 Subject: [PATCH 02/23] Introduce InvocationExceptionWrapper and add logic to IINvocation.ReturnValue and IInvocation.Exception. --- src/Moq/Invocation.cs | 9 ++++++++- src/Moq/InvocationExceptionWrapper.cs | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/Moq/InvocationExceptionWrapper.cs diff --git a/src/Moq/Invocation.cs b/src/Moq/Invocation.cs index db641e315..cbb08e0ec 100644 --- a/src/Moq/Invocation.cs +++ b/src/Moq/Invocation.cs @@ -71,7 +71,9 @@ public MethodInfo MethodImplementation public object ReturnValue { - get => this.returnValue; + get => this.returnValue is InvocationExceptionWrapper + ? null + : this.returnValue; set { Debug.Assert(this.returnValue == null); @@ -79,6 +81,11 @@ public object ReturnValue } } + public Exception Exception + => this.returnValue is InvocationExceptionWrapper wrapper + ? wrapper.Exception + : null; + public bool IsVerified => this.verified; /// diff --git a/src/Moq/InvocationExceptionWrapper.cs b/src/Moq/InvocationExceptionWrapper.cs new file mode 100644 index 000000000..7b9f7ab39 --- /dev/null +++ b/src/Moq/InvocationExceptionWrapper.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Moq +{ + /// + /// Internal type to mark invocation results as "exception occurred during execution". The type just + /// wraps the Exception so a thrown exception can be distinguished from an + /// return by the invocation. + /// + internal readonly struct InvocationExceptionWrapper + { + public InvocationExceptionWrapper(Exception exception) + { + Exception = exception; + } + + public Exception Exception { get; } + } +} From 01b932960d1e41c14d74edc46094c29e4f72c589 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 16:14:02 +0100 Subject: [PATCH 03/23] Add inheritdoc doc comments. --- src/Moq/Invocation.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Moq/Invocation.cs b/src/Moq/Invocation.cs index cbb08e0ec..97c979d72 100644 --- a/src/Moq/Invocation.cs +++ b/src/Moq/Invocation.cs @@ -69,6 +69,7 @@ public MethodInfo MethodImplementation public Type ProxyType => this.proxyType; + /// public object ReturnValue { get => this.returnValue is InvocationExceptionWrapper @@ -81,6 +82,7 @@ public object ReturnValue } } + /// public Exception Exception => this.returnValue is InvocationExceptionWrapper wrapper ? wrapper.Exception From dd5c654698359f26dc95bfeedda0fbfa51fc7a79 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 16:59:59 +0100 Subject: [PATCH 04/23] Add tests for IInvocation.ReturnValue --- tests/Moq.Tests/InvocationsFixture.cs | 48 ++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index d67258d30..4a5a1f6c7 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -45,11 +45,57 @@ public void MockInvocationsIncludeArguments() var invocation = mock.Invocations[0]; - var expectedArguments = new[] {obj}; + var expectedArguments = new[] { obj }; Assert.Equal(expectedArguments, invocation.Arguments); } + [Fact] + public void MockInvocationsIncludeReturnValue_NoSetup() + { + var mock = new Mock(); + + var obj = new object(); + + mock.Object.CompareTo(obj); + + var invocation = mock.Invocations[0]; + + Assert.Equal(0, invocation.ReturnValue); + Assert.Null(invocation.Exception); + } + + [Fact] + public void MockInvocationsIncludeReturnValue_Setup() + { + var mock = new Mock(); + var obj = new object(); + mock.Setup(c => c.CompareTo(obj)).Returns(42); + + mock.Object.CompareTo(obj); + + var invocation = mock.Invocations[0]; + + Assert.Equal(42, invocation.ReturnValue); + Assert.Null(invocation.Exception); + } + + [Fact] + public void MockInvocationsIncludeReturnValue_BaseCall() + { + var mock = new Mock(1) // seed: 1 + { + CallBase = true, + }; + + mock.Object.Next(); + + var invocation = mock.Invocations[0]; + + Assert.Equal(534011718, invocation.ReturnValue); + Assert.Null(invocation.Exception); + } + [Fact] public void MockInvocationsCanBeEnumerated() { From 19361829454aa6979470108c8374ae3884149fd7 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 17:00:26 +0100 Subject: [PATCH 05/23] Add test MockInvocationsIncludeException_Setup --- tests/Moq.Tests/InvocationsFixture.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index 4a5a1f6c7..7d707400e 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -96,6 +96,26 @@ public void MockInvocationsIncludeReturnValue_BaseCall() Assert.Null(invocation.Exception); } + [Fact] + public void MockInvocationsIncludeException_Setup() + { + var mock = new Mock(); + var exception = new Exception("Message"); + mock.Setup(c => c.CompareTo(It.IsAny())).Throws(exception); + + try + { + mock.Object.CompareTo(null); + } + catch (Exception thrown) + { + Assert.Equal(exception.Message, thrown.Message); + var invocation = mock.Invocations[0]; + + Assert.Same(thrown, invocation.Exception); + } + } + [Fact] public void MockInvocationsCanBeEnumerated() { From 67793f34a29f3b78da5b3d7a6394d4d3f86480f3 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 17:01:02 +0100 Subject: [PATCH 06/23] Add exception handling to Interceptor.Intercept --- src/Moq/ProxyFactories/CastleProxyFactory.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Moq/ProxyFactories/CastleProxyFactory.cs b/src/Moq/ProxyFactories/CastleProxyFactory.cs index e99e9e57d..382b568ca 100644 --- a/src/Moq/ProxyFactories/CastleProxyFactory.cs +++ b/src/Moq/ProxyFactories/CastleProxyFactory.cs @@ -101,6 +101,15 @@ public void Intercept(Castle.DynamicProxy.IInvocation underlying) this.interceptor.Intercept(invocation); underlying.ReturnValue = invocation.ReturnValue; } + catch (MockException) + { + throw; + } + catch (Exception ex) + { + invocation.ReturnValue = new InvocationExceptionWrapper(ex); + throw; + } finally { invocation.DetachFromUnderlying(); @@ -146,8 +155,8 @@ public override bool ShouldInterceptMethod(Type type, MethodInfo method) private static bool IsRelevantObjectMethod(MethodInfo method) { return method.DeclaringType == typeof(object) && (method.Name == nameof(object.ToString) - || method.Name == nameof(object.Equals) - || method.Name == nameof(object.GetHashCode)); + || method.Name == nameof(object.Equals) + || method.Name == nameof(object.GetHashCode)); } } } From e49273f62bce4416fabeb0686f3497945408b198 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 17:19:52 +0100 Subject: [PATCH 07/23] Add test for "CallBase = true" and method returning an exception type. --- tests/Moq.Tests/InvocationsFixture.cs | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index 7d707400e..c481a3ceb 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -2,6 +2,8 @@ // All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. using System; +using System.Collections; +using System.Collections.Generic; using System.Linq; using Xunit; @@ -96,11 +98,27 @@ public void MockInvocationsIncludeReturnValue_BaseCall() Assert.Null(invocation.Exception); } + [Fact] + public void MockInvocationsIncludeReturnValue_ReturnsException() + { + var mock = new Mock(); + var returnValue = new Exception(); + mock.Setup(c => c.Clone()).Returns(returnValue); + + mock.Object.Clone(); + + var invocation = mock.Invocations[0]; + + Assert.Equal(returnValue, invocation.ReturnValue); + Assert.Null(invocation.Exception); + } + [Fact] public void MockInvocationsIncludeException_Setup() { var mock = new Mock(); var exception = new Exception("Message"); + var exceptionThrownAndHandled = false; mock.Setup(c => c.CompareTo(It.IsAny())).Throws(exception); try @@ -113,7 +131,22 @@ public void MockInvocationsIncludeException_Setup() var invocation = mock.Invocations[0]; Assert.Same(thrown, invocation.Exception); + exceptionThrownAndHandled = true; } + + Assert.True(exceptionThrownAndHandled); + } + + [Fact] + public void MockInvocationsIncludeException_BaseCall() + { + var mock = new Mock>() + { + CallBase = true, + }; + + Assert.Throws(() => mock.Object.GetRange(1, 1)); + Assert.Empty(mock.Invocations); } [Fact] From a66310e081bbc980cc658ac2f05c8eb90c2862af Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 17:21:13 +0100 Subject: [PATCH 08/23] Add code comment why mock.Invocations is empty. --- tests/Moq.Tests/InvocationsFixture.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index c481a3ceb..c1df9365b 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -146,6 +146,7 @@ public void MockInvocationsIncludeException_BaseCall() }; Assert.Throws(() => mock.Object.GetRange(1, 1)); + // Base-call exceptions are not recorded Assert.Empty(mock.Invocations); } From 1e18affbd4f7ebca592c0ad12e5968811d977caf Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 20:37:13 +0100 Subject: [PATCH 09/23] Add header to InvocationExceptionWrapper --- src/Moq/InvocationExceptionWrapper.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Moq/InvocationExceptionWrapper.cs b/src/Moq/InvocationExceptionWrapper.cs index 7b9f7ab39..213c44e13 100644 --- a/src/Moq/InvocationExceptionWrapper.cs +++ b/src/Moq/InvocationExceptionWrapper.cs @@ -1,8 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors. +// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt. + +using System; namespace Moq { From 988feb0594c1eaa873d0dcb8e0aca6fd760c627b Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 20:39:09 +0100 Subject: [PATCH 10/23] Change doc comments on IInvocation. --- src/Moq/IInvocation.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Moq/IInvocation.cs b/src/Moq/IInvocation.cs index 23f03dc02..cd9e6a21b 100644 --- a/src/Moq/IInvocation.cs +++ b/src/Moq/IInvocation.cs @@ -33,16 +33,13 @@ public interface IInvocation bool IsVerified { get; } /// - /// Gets the return value of the invocation. + /// The value being returned for a non-void method if no exception was thrown. /// object ReturnValue { get; } /// - /// Gets the exception, thrown during the invocation. + /// Optional exception if the method invocation results in an exception being thrown. /// - /// - /// Returns if no exception was raised. - /// Exception Exception { get; } } } \ No newline at end of file From a18d167384ff0a768789e52780d40747bcd391f8 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 20:40:25 +0100 Subject: [PATCH 11/23] Remove "inhertitdoc" from internal type. --- src/Moq/Invocation.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Moq/Invocation.cs b/src/Moq/Invocation.cs index 97c979d72..cbb08e0ec 100644 --- a/src/Moq/Invocation.cs +++ b/src/Moq/Invocation.cs @@ -69,7 +69,6 @@ public MethodInfo MethodImplementation public Type ProxyType => this.proxyType; - /// public object ReturnValue { get => this.returnValue is InvocationExceptionWrapper @@ -82,7 +81,6 @@ public object ReturnValue } } - /// public Exception Exception => this.returnValue is InvocationExceptionWrapper wrapper ? wrapper.Exception From 31f5ec7e3604b6dbc3880971da9c790147360a58 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 20:55:09 +0100 Subject: [PATCH 12/23] Harden test by replacing hard coded value by calculated random.Next --- tests/Moq.Tests/InvocationsFixture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index c1df9365b..372b78de4 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -94,7 +94,7 @@ public void MockInvocationsIncludeReturnValue_BaseCall() var invocation = mock.Invocations[0]; - Assert.Equal(534011718, invocation.ReturnValue); + Assert.Equal(new Random(Seed: 1).Next(), invocation.ReturnValue); Assert.Null(invocation.Exception); } From 09816d01f0dffe255ae65527d11d68beddd4eb16 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:01:18 +0100 Subject: [PATCH 13/23] Add MockInvocationsIncludeException_BaseCall_Virtual test --- tests/Moq.Tests/InvocationsFixture.cs | 32 ++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index 372b78de4..2ef6fa57d 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -138,7 +138,7 @@ public void MockInvocationsIncludeException_Setup() } [Fact] - public void MockInvocationsIncludeException_BaseCall() + public void MockInvocationsIncludeException_BaseCall_Nonvirtual() { var mock = new Mock>() { @@ -150,6 +150,31 @@ public void MockInvocationsIncludeException_BaseCall() Assert.Empty(mock.Invocations); } + [Fact] + public void MockInvocationsIncludeException_BaseCall_Virtual() + { + var mock = new Mock() + { + CallBase = true, + }; + var exceptionThrownAndHandled = false; + + try + { + mock.Object.ThrowingVirtualMethod(); + } + catch (Exception thrown) + { + Assert.Equal("Message", thrown.Message); + var invocation = mock.Invocations[0]; + + Assert.Same(thrown, invocation.Exception); + exceptionThrownAndHandled = true; + } + + Assert.True(exceptionThrownAndHandled); + } + [Fact] public void MockInvocationsCanBeEnumerated() { @@ -369,5 +394,10 @@ public FlagInitiallySetToTrue() public virtual bool Flag { get; set; } } + + public class Test + { + public virtual int ThrowingVirtualMethod() => throw new InvalidOperationException("Message"); + } } } From a064c982cf7dde9d9a568ee9b15591f033a9a8e0 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:10:59 +0100 Subject: [PATCH 14/23] Add test for behavior of MockException and remove exclusion of catch(MockException) --- src/Moq/ProxyFactories/CastleProxyFactory.cs | 4 ---- tests/Moq.Tests/InvocationsFixture.cs | 24 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Moq/ProxyFactories/CastleProxyFactory.cs b/src/Moq/ProxyFactories/CastleProxyFactory.cs index 382b568ca..897c7225b 100644 --- a/src/Moq/ProxyFactories/CastleProxyFactory.cs +++ b/src/Moq/ProxyFactories/CastleProxyFactory.cs @@ -101,10 +101,6 @@ public void Intercept(Castle.DynamicProxy.IInvocation underlying) this.interceptor.Intercept(invocation); underlying.ReturnValue = invocation.ReturnValue; } - catch (MockException) - { - throw; - } catch (Exception ex) { invocation.ReturnValue = new InvocationExceptionWrapper(ex); diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index 2ef6fa57d..d8145e23d 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -175,6 +175,30 @@ public void MockInvocationsIncludeException_BaseCall_Virtual() Assert.True(exceptionThrownAndHandled); } + [Fact] + public void MockInvocationsIncludeException_MockException() + { + var mock = new Mock(MockBehavior.Strict); + var exceptionThrownAndHandled = false; + + try + { + mock.Object.Clone(); + } + catch (MockException thrown) + { + Assert.Equal( +@"ICloneable.Clone() invocation failed with mock behavior Strict. +All invocations on the mock must have a corresponding setup.", thrown.Message); + var invocation = mock.Invocations[0]; + + Assert.Same(thrown, invocation.Exception); + exceptionThrownAndHandled = true; + } + + Assert.True(exceptionThrownAndHandled); + } + [Fact] public void MockInvocationsCanBeEnumerated() { From 22f35752304a74022da49855db6cdad894d960a6 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:13:19 +0100 Subject: [PATCH 15/23] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d50a10327..f6cbe09c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1 #### Added * New method overloads for `It.Is`, `It.IsIn`, and `It.IsNotIn` that compare values using a custom `IEqualityComparer` (@weitzhandler, #1064) -* New property `IInvocation.ReturnValue` to query recorded invocations return values (@MaStr11, #921) +* New properties `ReturnValue` and `Exception` on `IInvocation` to query recorded invocations return values or exceptions (@MaStr11, #921, #1077) ## 4.14.7 (2020-10-14) From f2cfc4c2d98c8e9c55ae92db93a81c3acf3904eb Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:26:14 +0100 Subject: [PATCH 16/23] Revert whitespace change --- src/Moq/ProxyFactories/CastleProxyFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Moq/ProxyFactories/CastleProxyFactory.cs b/src/Moq/ProxyFactories/CastleProxyFactory.cs index 897c7225b..ec1cf42a9 100644 --- a/src/Moq/ProxyFactories/CastleProxyFactory.cs +++ b/src/Moq/ProxyFactories/CastleProxyFactory.cs @@ -151,8 +151,8 @@ public override bool ShouldInterceptMethod(Type type, MethodInfo method) private static bool IsRelevantObjectMethod(MethodInfo method) { return method.DeclaringType == typeof(object) && (method.Name == nameof(object.ToString) - || method.Name == nameof(object.Equals) - || method.Name == nameof(object.GetHashCode)); + || method.Name == nameof(object.Equals) + || method.Name == nameof(object.GetHashCode)); } } } From 0ae91895845309d244dcb5ae3e67abdb4357508d Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:28:09 +0100 Subject: [PATCH 17/23] Revert whitespace change --- src/Moq/ProxyFactories/CastleProxyFactory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Moq/ProxyFactories/CastleProxyFactory.cs b/src/Moq/ProxyFactories/CastleProxyFactory.cs index ec1cf42a9..26d9775ec 100644 --- a/src/Moq/ProxyFactories/CastleProxyFactory.cs +++ b/src/Moq/ProxyFactories/CastleProxyFactory.cs @@ -151,8 +151,8 @@ public override bool ShouldInterceptMethod(Type type, MethodInfo method) private static bool IsRelevantObjectMethod(MethodInfo method) { return method.DeclaringType == typeof(object) && (method.Name == nameof(object.ToString) - || method.Name == nameof(object.Equals) - || method.Name == nameof(object.GetHashCode)); + || method.Name == nameof(object.Equals) + || method.Name == nameof(object.GetHashCode)); } } } From 605501578067518e4cbebabc48a9cf1c70121fe4 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:32:47 +0100 Subject: [PATCH 18/23] Use Assert.Throws instead of try/catch --- tests/Moq.Tests/InvocationsFixture.cs | 56 +++++++-------------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index d8145e23d..5576fbdc6 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -118,23 +118,15 @@ public void MockInvocationsIncludeException_Setup() { var mock = new Mock(); var exception = new Exception("Message"); - var exceptionThrownAndHandled = false; mock.Setup(c => c.CompareTo(It.IsAny())).Throws(exception); - try - { - mock.Object.CompareTo(null); - } - catch (Exception thrown) - { - Assert.Equal(exception.Message, thrown.Message); - var invocation = mock.Invocations[0]; + var thrown = Assert.Throws(() => mock.Object.CompareTo(null)); + + Assert.Equal(exception.Message, thrown.Message); - Assert.Same(thrown, invocation.Exception); - exceptionThrownAndHandled = true; - } + var invocation = mock.Invocations[0]; + Assert.Same(thrown, invocation.Exception); - Assert.True(exceptionThrownAndHandled); } [Fact] @@ -157,46 +149,28 @@ public void MockInvocationsIncludeException_BaseCall_Virtual() { CallBase = true, }; - var exceptionThrownAndHandled = false; - try - { - mock.Object.ThrowingVirtualMethod(); - } - catch (Exception thrown) - { - Assert.Equal("Message", thrown.Message); - var invocation = mock.Invocations[0]; + var thrown = Assert.Throws(() => mock.Object.ThrowingVirtualMethod()); - Assert.Same(thrown, invocation.Exception); - exceptionThrownAndHandled = true; - } + Assert.Equal("Message", thrown.Message); - Assert.True(exceptionThrownAndHandled); + var invocation = mock.Invocations[0]; + Assert.Same(thrown, invocation.Exception); } [Fact] public void MockInvocationsIncludeException_MockException() { var mock = new Mock(MockBehavior.Strict); - var exceptionThrownAndHandled = false; - try - { - mock.Object.Clone(); - } - catch (MockException thrown) - { - Assert.Equal( -@"ICloneable.Clone() invocation failed with mock behavior Strict. -All invocations on the mock must have a corresponding setup.", thrown.Message); - var invocation = mock.Invocations[0]; + var thrown = Assert.Throws(() => mock.Object.Clone()); - Assert.Same(thrown, invocation.Exception); - exceptionThrownAndHandled = true; - } + Assert.Equal( + @"ICloneable.Clone() invocation failed with mock behavior Strict. +All invocations on the mock must have a corresponding setup.", thrown.Message); - Assert.True(exceptionThrownAndHandled); + var invocation = mock.Invocations[0]; + Assert.Same(thrown, invocation.Exception); } [Fact] From e1fa79321287d7aeb8befb9182e34cd59604b6bd Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:34:46 +0100 Subject: [PATCH 19/23] Formatting --- tests/Moq.Tests/InvocationsFixture.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index 5576fbdc6..0b300e1e0 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -126,7 +126,6 @@ public void MockInvocationsIncludeException_Setup() var invocation = mock.Invocations[0]; Assert.Same(thrown, invocation.Exception); - } [Fact] From b2c07f3c67964ddaf8fb5dbf7dd21b7294a343bc Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:39:26 +0100 Subject: [PATCH 20/23] Whitespace --- tests/Moq.Tests/InvocationsFixture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index 0b300e1e0..d00da1c35 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -165,7 +165,7 @@ public void MockInvocationsIncludeException_MockException() var thrown = Assert.Throws(() => mock.Object.Clone()); Assert.Equal( - @"ICloneable.Clone() invocation failed with mock behavior Strict. +@"ICloneable.Clone() invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.", thrown.Message); var invocation = mock.Invocations[0]; From b9a4d63b2da8634707eb0e55cc7a55be4504a395 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 14 Oct 2020 21:47:30 +0100 Subject: [PATCH 21/23] Fix failing test --- tests/Moq.Tests/InvocationsFixture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index d00da1c35..d38ca2c14 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -149,7 +149,7 @@ public void MockInvocationsIncludeException_BaseCall_Virtual() CallBase = true, }; - var thrown = Assert.Throws(() => mock.Object.ThrowingVirtualMethod()); + var thrown = Assert.Throws(() => mock.Object.ThrowingVirtualMethod()); Assert.Equal("Message", thrown.Message); From 3f2a43ba7d929de7ddb2d2a10caaab2ba442ec54 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 15 Oct 2020 13:27:22 +0100 Subject: [PATCH 22/23] Remove misleading test --- tests/Moq.Tests/InvocationsFixture.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index d38ca2c14..6c4cccf1b 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -128,19 +128,6 @@ public void MockInvocationsIncludeException_Setup() Assert.Same(thrown, invocation.Exception); } - [Fact] - public void MockInvocationsIncludeException_BaseCall_Nonvirtual() - { - var mock = new Mock>() - { - CallBase = true, - }; - - Assert.Throws(() => mock.Object.GetRange(1, 1)); - // Base-call exceptions are not recorded - Assert.Empty(mock.Invocations); - } - [Fact] public void MockInvocationsIncludeException_BaseCall_Virtual() { From 3b5be649f0128bd361e5fcfd4f5f5db9380318eb Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 15 Oct 2020 13:30:44 +0100 Subject: [PATCH 23/23] Assert `thrown.Reasons` instead of `thrown.Message` --- tests/Moq.Tests/InvocationsFixture.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Moq.Tests/InvocationsFixture.cs b/tests/Moq.Tests/InvocationsFixture.cs index 6c4cccf1b..8e4558a4f 100644 --- a/tests/Moq.Tests/InvocationsFixture.cs +++ b/tests/Moq.Tests/InvocationsFixture.cs @@ -121,7 +121,7 @@ public void MockInvocationsIncludeException_Setup() mock.Setup(c => c.CompareTo(It.IsAny())).Throws(exception); var thrown = Assert.Throws(() => mock.Object.CompareTo(null)); - + Assert.Equal(exception.Message, thrown.Message); var invocation = mock.Invocations[0]; @@ -151,9 +151,7 @@ public void MockInvocationsIncludeException_MockException() var thrown = Assert.Throws(() => mock.Object.Clone()); - Assert.Equal( -@"ICloneable.Clone() invocation failed with mock behavior Strict. -All invocations on the mock must have a corresponding setup.", thrown.Message); + Assert.Equal(MockExceptionReasons.NoSetup, thrown.Reasons); var invocation = mock.Invocations[0]; Assert.Same(thrown, invocation.Exception);