Reputation: 99
I am trying to create a xunit test for a method that checks for DBNull.Value. I am currently using InlineData to create the test but it is giving an error when attempting to use 'DBNull.Value' as my test param.
[Theory]
[InlineData(null)]
[InlineData(DBNull.Value)]
public void GetStringorNullNegativeTest(object value)
{
//arrange, act
var _resultString = value == null ? "" : value.ToString().Trim();
var _returnString = value.GetStringorNull();
//assert
Assert.NotEqual(_resultString, _returnString);
}
public static string GetStringorNull(this System.Object o)
{
if (o == null || o == DBNull.Value)
return null;
if (o is string)
{
string s = (string)o;
if (string.IsNullOrWhiteSpace(s))
return null;
else
return s.Trim();
}
return o.ToString().Trim();
}
Is there a simple way to check for 'DBNull.Value' in the test without completely refactoring the test?
Upvotes: 0
Views: 343
Reputation: 89
The following does require changing the way you're handling the test itself from InlineData
to MemberData
. Make your GetStringorNullNegativeTest
test look like below, adding an additional MemberData
method to facilitate any future tests too.
Similar to what Ken B was mentioning. Dai added an asterisks to understand the difference between the two types of test
What you have is the MemberData can run multiple tests, and more features than the InlineData
restrictions of attributes. I added your null
test as well.
[Theory]
[MemberData(nameof(GetStringorNullNegativeTest_MemberData))]
public void GetStringorNullNegativeTest(object value)
{
//arrange, act
var _resultString = value == null ? "" : value.ToString().Trim();
var _returnString = value.GetStringorNull();
//assert
Assert.NotEqual(_resultString, _returnString);
}
public static IEnumerable<object[]> GetStringorNullNegativeTest_MemberData()
{
yield return new object[] { null };
yield return new object[] { DBNull.Value };
}
Upvotes: 0
Reputation: 99
I ended up using the MemberData option as suggested. Changed to the below and it works.
public static IEnumerable<object[]> DBNullObject =>
new List<object[]>
{
new object[] { DBNull.Value }
};
[Theory]
[MemberData(nameof(DBNullObject))]
public void GetStringorNullNegativeTest(object value)
{
//arrange, act
var _resultString = value == null ? "" : value.ToString().Trim();
var _returnString = value.GetStringorNull();
//assert
Assert.NotEqual(_resultString, _returnString);
}
Upvotes: 2
Reputation: 155428
const
expressions to be used as values for attributes, namely:
String
literals (including nameof()
expressions).null
constant reference.Single
and Double
) literals.
0M
literals.enum
members.const
.typeof()
expressions.String
values, reference-types cannot be used in attribute use-sites.DBNull
is a class
, i.e. a reference-type.DBNull.Value
is a public static readonly
field, not a const
field.DBNull.Value
cannot be used in an attribute use-site directly.Instead, use some other means of representing a DBNull
... for example:
public enum GetStringOrNullTestMode
{
UseValue,
UseDBNull
}
[Theory]
[InlineData(GetStringOrNullTestMode.UseValue, null)]
[InlineData(GetStringOrNullTestMode.UseValue, "")]
[InlineData(GetStringOrNullTestMode.UseValue, "abc123")]
[InlineData(GetStringOrNullTestMode.UseDBNull, null)]
public void GetStringorNullNegativeTest( GetStringOrNullTestMode mode, Object? value )
{
if( mode == GetStringOrNullTestMode.UseDBNull ) value = DBNull.Value;
// arrange, act
var actual = value == null ? "" : value.ToString().Trim();
var returnString = value.GetStringorNull();
// assert
Assert.NotEqual_resultString, _returnString);
}
Another approach is to use hand-written [Fact]
methods that create and pass non-const
values into the same orignal [Theory]
test method, e.g.:
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData("abc123")]
public void GetStringorNullNegativeTest( Object? value )
{
if( mode == GetStringOrNullTestMode.UseDBNull ) value = DBNull.Value;
// arrange, act
var actual = value == null ? "" : value.ToString().Trim();
var returnString = value.GetStringorNull();
// assert
Assert.NotEqual_resultString, _returnString);
}
[Fact]
public void GetStringorNullNegativeTestWithDBNull()
{
this.GetStringorNullNegativeTest( value: DBNull.Value );
}
Upvotes: 2