diff --git a/src/NSubstitute/Extensions/ReturnsExtensions.cs b/src/NSubstitute/Extensions/ReturnsExtensions.cs index 7877ac1d..29d5b82c 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 94501058..8ffc22c4 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 7dcdc9b3..9871d126 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() {