From 3946fe89dec729af2332f3d86deb12efc863028a Mon Sep 17 00:00:00 2001 From: Stedoss <29103029+Stedoss@users.noreply.github.com> Date: Sat, 18 Jun 2022 14:56:06 +0100 Subject: [PATCH] Add support for `ReturnsNull` calls for nullable value types --- .../Extensions/ReturnsExtensions.cs | 36 +++++++++++++ .../Infrastructure/ISomething.cs | 6 +++ .../ReturningResults.cs | 53 +++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/src/NSubstitute/Extensions/ReturnsExtensions.cs b/src/NSubstitute/Extensions/ReturnsExtensions.cs index 7877ac1d0..29d5b82c8 100644 --- a/src/NSubstitute/Extensions/ReturnsExtensions.cs +++ b/src/NSubstitute/Extensions/ReturnsExtensions.cs @@ -20,6 +20,18 @@ public static ConfiguredCall ReturnsNull(this T value) where T : class => public static ConfiguredCall ReturnsNullForAnyArgs(this T value) where T : class => value.ReturnsForAnyArgs(default(T)); + /// + /// Set null as returned value for this call. + /// + public static ConfiguredCall ReturnsNull(this T? value) where T : struct => + value.Returns(default(T?)); + + /// + /// Set null as returned value for this call made with any arguments. + /// + public static ConfiguredCall ReturnsNullForAnyArgs(this T? value) where T : struct => + value.ReturnsForAnyArgs(default(T?)); + /// /// Set null as returned value for this call. /// @@ -46,5 +58,29 @@ public static ConfiguredCall ReturnsNullForAnyArgs(this Task value) where /// public static ConfiguredCall ReturnsNullForAnyArgs(this ValueTask value) where T : class => value.ReturnsForAnyArgs(default(T)); + + /// + /// Set null as returned value for this call. + /// + public static ConfiguredCall ReturnsNull(this Task value) where T : struct => + value.Returns(default(T?)); + + /// + /// Set null as returned value for this call made with any arguments. + /// + public static ConfiguredCall ReturnsNullForAnyArgs(this Task value) where T : struct => + value.ReturnsForAnyArgs(default(T?)); + + /// + /// Set null as returned value for this call. + /// + public static ConfiguredCall ReturnsNull(this ValueTask value) where T : struct => + value.Returns(default(T?)); + + /// + /// Set null as returned value for this call made with any arguments. + /// + public static ConfiguredCall ReturnsNullForAnyArgs(this ValueTask value) where T : struct => + value.ReturnsForAnyArgs(default(T?)); } } diff --git a/tests/NSubstitute.Acceptance.Specs/Infrastructure/ISomething.cs b/tests/NSubstitute.Acceptance.Specs/Infrastructure/ISomething.cs index 94501058b..8ffc22c4f 100644 --- a/tests/NSubstitute.Acceptance.Specs/Infrastructure/ISomething.cs +++ b/tests/NSubstitute.Acceptance.Specs/Infrastructure/ISomething.cs @@ -16,6 +16,8 @@ public interface ISomething int MethodWithRefParameter(int arg1, ref int arg2); int MethodWithMultipleRefParameters(int arg1, ref int arg2, ref int arg3); int MethodWithOutParameter(int arg1, out int arg2); + int? NullableCount(); + int? NullableWithParams(int i, string s); object this[string key] { get; set; } System.Threading.Tasks.Task Async(); @@ -26,6 +28,8 @@ public interface ISomething System.Threading.Tasks.Task SayAsync(string s); System.Threading.Tasks.Task SomeActionAsync(); System.Threading.Tasks.Task SomeActionWithParamsAsync(int i, string s); + System.Threading.Tasks.Task NullableCountAsync(); + System.Threading.Tasks.Task NullableWithParamsAsync(int i, string s); System.Threading.Tasks.ValueTask CountValueTaskAsync(); System.Threading.Tasks.ValueTask EchoValueTaskAsync(int i); @@ -33,5 +37,7 @@ public interface ISomething System.Threading.Tasks.ValueTask SayValueTaskAsync(string s); System.Threading.Tasks.ValueTask SomeActionValueTaskAsync(); System.Threading.Tasks.ValueTask SomeActionWithParamsValueTaskAsync(int i, string s); + System.Threading.Tasks.ValueTask NullableCountValueTaskAsync(); + System.Threading.Tasks.ValueTask NullableCountValueTaskWithParamsAsync(int i, string s); } } \ No newline at end of file diff --git a/tests/NSubstitute.Acceptance.Specs/ReturningResults.cs b/tests/NSubstitute.Acceptance.Specs/ReturningResults.cs index 7dcdc9b3b..9871d126d 100644 --- a/tests/NSubstitute.Acceptance.Specs/ReturningResults.cs +++ b/tests/NSubstitute.Acceptance.Specs/ReturningResults.cs @@ -330,6 +330,59 @@ public void Return_multiple_ValueTask_async_results_from_funcs() Assert.That(_something.CountValueTaskAsync().Result, Is.EqualTo(3), "Fourth return"); } + [Test] + public void Returns_null_for_nullable_value_type() + { + _something.NullableCount().ReturnsNull(); + + Assert.That(_something.NullableCount(), Is.Null); + } + + [Test] + public void Returns_null_for_any_args_when_nullable_value_type() + { + _something.NullableWithParams(2, "test").ReturnsNullForAnyArgs(); + + Assert.That(_something.NullableWithParams(123, "something else"), Is.Null); + } + + [Test] + public void Returns_null_for_task_of_null_value_type() + { + _something.NullableCountAsync().ReturnsNull(); + + Assert.That(_something.NullableCountAsync(), Is.TypeOf>()); + Assert.That(_something.NullableCountAsync().Result, Is.Null); + } + + [Test] + public void Returns_null_for_any_args_when_task_of_null_value_type() + { + _something.NullableWithParamsAsync(2, "test").ReturnsNullForAnyArgs(); + + Assert.That(_something.NullableWithParamsAsync(123, "something else"), Is.TypeOf>()); + Assert.That(_something.NullableWithParamsAsync(123, "something else").Result, Is.Null); + } + + [Test] + public void Returns_null_for_TaskValue_for_null_value_type() + { + _something.NullableCountValueTaskAsync().ReturnsNull(); + + Assert.That(_something.NullableCountValueTaskAsync(), Is.TypeOf>()); + Assert.That(_something.NullableCountValueTaskAsync().Result, Is.Null); + } + + [Test] + public void Returns_null_for_any_args_when_TaskValue_is_of_null_value_type() + { + _something.NullableCountValueTaskWithParamsAsync(2, "test").ReturnsNullForAnyArgs(); + + Assert.That(_something.NullableCountValueTaskWithParamsAsync(123, "something else"), + Is.TypeOf>()); + Assert.That(_something.NullableCountValueTaskWithParamsAsync(123, "something else").Result, Is.Null); + } + [SetUp] public void SetUp() {