Skip to content

Commit

Permalink
Merge pull request #692 from Stedoss/value-type-nulls
Browse files Browse the repository at this point in the history
Add support for `ReturnsNull` calls for nullable value types
  • Loading branch information
dtchepak authored Jul 10, 2022
2 parents 8d00402 + 3946fe8 commit 5fa96da
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/NSubstitute/Extensions/ReturnsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ public static ConfiguredCall ReturnsNull<T>(this T value) where T : class =>
public static ConfiguredCall ReturnsNullForAnyArgs<T>(this T value) where T : class =>
value.ReturnsForAnyArgs(default(T));

/// <summary>
/// Set null as returned value for this call.
/// </summary>
public static ConfiguredCall ReturnsNull<T>(this T? value) where T : struct =>
value.Returns(default(T?));

/// <summary>
/// Set null as returned value for this call made with any arguments.
/// </summary>
public static ConfiguredCall ReturnsNullForAnyArgs<T>(this T? value) where T : struct =>
value.ReturnsForAnyArgs(default(T?));

/// <summary>
/// Set null as returned value for this call.
/// </summary>
Expand All @@ -46,5 +58,29 @@ public static ConfiguredCall ReturnsNullForAnyArgs<T>(this Task<T> value) where
/// <returns></returns>
public static ConfiguredCall ReturnsNullForAnyArgs<T>(this ValueTask<T> value) where T : class =>
value.ReturnsForAnyArgs(default(T));

/// <summary>
/// Set null as returned value for this call.
/// </summary>
public static ConfiguredCall ReturnsNull<T>(this Task<T?> value) where T : struct =>
value.Returns(default(T?));

/// <summary>
/// Set null as returned value for this call made with any arguments.
/// </summary>
public static ConfiguredCall ReturnsNullForAnyArgs<T>(this Task<T?> value) where T : struct =>
value.ReturnsForAnyArgs(default(T?));

/// <summary>
/// Set null as returned value for this call.
/// </summary>
public static ConfiguredCall ReturnsNull<T>(this ValueTask<T?> value) where T : struct =>
value.Returns(default(T?));

/// <summary>
/// Set null as returned value for this call made with any arguments.
/// </summary>
public static ConfiguredCall ReturnsNullForAnyArgs<T>(this ValueTask<T?> value) where T : struct =>
value.ReturnsForAnyArgs(default(T?));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -26,12 +28,16 @@ public interface ISomething
System.Threading.Tasks.Task<string> SayAsync(string s);
System.Threading.Tasks.Task<SomeClass> SomeActionAsync();
System.Threading.Tasks.Task<SomeClass> SomeActionWithParamsAsync(int i, string s);
System.Threading.Tasks.Task<int?> NullableCountAsync();
System.Threading.Tasks.Task<int?> NullableWithParamsAsync(int i, string s);

System.Threading.Tasks.ValueTask<int> CountValueTaskAsync();
System.Threading.Tasks.ValueTask<string> EchoValueTaskAsync(int i);
System.Threading.Tasks.ValueTask<int> AnythingValueTaskAsync(object stuff);
System.Threading.Tasks.ValueTask<string> SayValueTaskAsync(string s);
System.Threading.Tasks.ValueTask<SomeClass> SomeActionValueTaskAsync();
System.Threading.Tasks.ValueTask<SomeClass> SomeActionWithParamsValueTaskAsync(int i, string s);
System.Threading.Tasks.ValueTask<int?> NullableCountValueTaskAsync();
System.Threading.Tasks.ValueTask<int?> NullableCountValueTaskWithParamsAsync(int i, string s);
}
}
53 changes: 53 additions & 0 deletions tests/NSubstitute.Acceptance.Specs/ReturningResults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Task<int?>>());
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<Task<int?>>());
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<ValueTask<int?>>());
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<ValueTask<int?>>());
Assert.That(_something.NullableCountValueTaskWithParamsAsync(123, "something else").Result, Is.Null);
}

[SetUp]
public void SetUp()
{
Expand Down

0 comments on commit 5fa96da

Please sign in to comment.