In the following code, o[0].AccountEnabled
has type bool
while graphUsers[0].AccountEnabled
has type bool?
.
Without the explicit cast to bool?
, I get the following error:
'bool' does not contain a definition for 'ShouldBe' and the best extension method overload 'ShouldBeTestExtensions.ShouldBe<bool?>(bool?, bool?, string?)' requires a receiver of type 'bool?'CS1929
How should I compare the values of non-nullable and nullable types using Shouldly? xUnit has no problems with this using Assert.Equal()
I prefer to not cast the extension method receiver to a nullable type for every such comparison.
Furthermore, how does it even work with the nullable cast ((bool?)
)? The definition for ShouldBe
is:
public static void ShouldBe<T>(
[NotNullIfNotNull(nameof(expected))] this T? actual,
[NotNullIfNotNull(nameof(actual))] T? expected,
string? customMessage = null)
{
if (ShouldlyConfiguration.CompareAsObjectTypes.Contains(typeof(T).FullName!) || typeof(T) == typeof(string))
actual.AssertAwesomely(v => Is.Equal(v, expected, new ObjectEqualityComparer<T>()), actual, expected, customMessage);
else
actual.AssertAwesomely(v => Is.Equal(v, expected), actual, expected, customMessage);
}
So, if T
is bool?
, then it would accept arguments of type bool??
, which isn't a valid type.
Code:
owners.ShouldSatisfyAllConditions(
o => o.Count.ShouldBe(graphUsers.Count),
o => o[0].Id.ShouldBe(Guid.Parse(graphUsers[0].Id!)),
o => o[0].DisplayName.ShouldBe(graphUsers[0].DisplayName),
o => o[0].GivenName.ShouldBe(graphUsers[0].GivenName),
o => o[0].Surname.ShouldBe(graphUsers[0].Surname),
o => o[0].UserPrincipalName.ShouldBe(graphUsers[0].UserPrincipalName),
o => o[0].Email.ShouldBe(graphUsers[0].Mail),
o => ((bool?)o[0].AccountEnabled).ShouldBe(graphUsers[0].AccountEnabled)
);
In the following code, o[0].AccountEnabled
has type bool
while graphUsers[0].AccountEnabled
has type bool?
.
Without the explicit cast to bool?
, I get the following error:
'bool' does not contain a definition for 'ShouldBe' and the best extension method overload 'ShouldBeTestExtensions.ShouldBe<bool?>(bool?, bool?, string?)' requires a receiver of type 'bool?'CS1929
How should I compare the values of non-nullable and nullable types using Shouldly? xUnit has no problems with this using Assert.Equal()
I prefer to not cast the extension method receiver to a nullable type for every such comparison.
Furthermore, how does it even work with the nullable cast ((bool?)
)? The definition for ShouldBe
is:
public static void ShouldBe<T>(
[NotNullIfNotNull(nameof(expected))] this T? actual,
[NotNullIfNotNull(nameof(actual))] T? expected,
string? customMessage = null)
{
if (ShouldlyConfiguration.CompareAsObjectTypes.Contains(typeof(T).FullName!) || typeof(T) == typeof(string))
actual.AssertAwesomely(v => Is.Equal(v, expected, new ObjectEqualityComparer<T>()), actual, expected, customMessage);
else
actual.AssertAwesomely(v => Is.Equal(v, expected), actual, expected, customMessage);
}
So, if T
is bool?
, then it would accept arguments of type bool??
, which isn't a valid type.
Code:
owners.ShouldSatisfyAllConditions(
o => o.Count.ShouldBe(graphUsers.Count),
o => o[0].Id.ShouldBe(Guid.Parse(graphUsers[0].Id!)),
o => o[0].DisplayName.ShouldBe(graphUsers[0].DisplayName),
o => o[0].GivenName.ShouldBe(graphUsers[0].GivenName),
o => o[0].Surname.ShouldBe(graphUsers[0].Surname),
o => o[0].UserPrincipalName.ShouldBe(graphUsers[0].UserPrincipalName),
o => o[0].Email.ShouldBe(graphUsers[0].Mail),
o => ((bool?)o[0].AccountEnabled).ShouldBe(graphUsers[0].AccountEnabled)
);
Share
Improve this question
edited Feb 2 at 17:47
Mark Seemann
233k49 gold badges447 silver badges775 bronze badges
asked Feb 2 at 17:20
ShuzhengShuzheng
14k29 gold badges120 silver badges229 bronze badges
2 Answers
Reset to default 1I don't really know Shouldly, but it looks as though you can use either ShouldBeAssignableTo
or ShouldBeEquivalentTo
if you don't want to use C#'s built-in cast syntax.
This test passes:
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Test(bool b)
{
bool? bOrNull = b;
b.ShouldBeAssignableTo<bool?>().ShouldBe(bOrNull);
b.ShouldBeEquivalentTo(bOrNull);
}
I'd probably prefer the second option myself.
In my opinion, you could split this assertion in two parts:
- assert that nullable value is not null (since you expect it to be equal to bool, so it has to have a value)
- assert that value of nullable bool is expected With Shouldly, it would look like:
[Fact]
public void Test1()
{
bool? nb = true;
bool b = true;
nb.ShouldNotBeNull();
b.ShouldBe(nb.Value);
}