xUnit理论指导作为参数
xUnit theory guids as parametr
我有测试字符串是否为 GUID 的扩展方法。
public static bool IsGuid(this string str)
{
if(str == null)
throw new ArgumentNullException(str, "Argument can not be NULL");
Guid guidFromString;
return Guid.TryParse(str, out guidFromString);
}
我想通过 xUnit 和 Theory 对其进行测试。
对于字符串,它正在工作:
[Theory, InlineData(""), InlineData(" ")]
public void IsGuid_EmptyOrWhiteSpace_ShouldReturnFalse(string str)
{
// Arrange
bool result;
// Act
result = str.IsGuid();
// Assert
Assert.False(result);
}
但是我如何才能为 Guid 数组做到这一点?我需要测试 Guid.Empty' and
Guid.NewGuid`。
这行不通:
[Theory, MemberData(nameof(Guids))]
public void IsGuid_EmptyOrValidGuid_ShouldReturnTrue(string str)
{
// Arrange
bool result;
// Act
result = str.IsGuid();
// Assert
Assert.False(result);
}
public static IEnumerable<string> Guids
{
get
{
yield return Guid.Empty.ToString();
yield return Guid.NewGuid().ToString();
}
}
@编辑
测试失败,因为
System.ArgumentException
Property Guids on ExtensionsLibraryTests.StringExtensions.xUnitStringExtensionsTests yielded an item that is not an object[]
at Xunit.MemberDataAttribute.ConvertDataItem(MethodInfo testMethod, Object item)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at Xunit.Sdk.XunitTheoryTestCaseRunner.<AfterTestCaseStartingAsync>d__7.MoveNext()
您的测试方法目前只有一个参数——字符串——但并非必须如此。如果您的测试方法有 3 个参数怎么办?你怎么把它打包成 IEnumerable<what-here?>
因此,当您使用 xUnit 的 'property data' 功能时,xUnit 要求 属性 的形式为 IEnumerable<object[]>
public static IEnumerable<object[]> Guids
{
get
{
yield return new object[]{ "" };
yield return new object[]{ " " };
}
}
这应该可以解决眼前的问题。但是,我鼓励您尝试这种布局:
[Theory, MemberData(nameof(Guids))]
public void thinkofsomesmartname(bool expectedResult, string text)
{
bool result = text.IsGuid();
Assert.Equal(expectedResult, result);
}
public static IEnumerable<object[]> Guids
{
get
{
yield return new object[]{ false, "" };
yield return new object[]{ false, " " };
yield return new object[]{ true, Guid.NewGuid().ToString() };
}
}
当然,通过数据集传递 'expected result' 有点麻烦,这使得发明测试名称有点困难。您可以创建两个数据集:错误和良好,并制作两种测试方法,一种使用 Assert.False,一种使用 Assert.True.. 但由于它是非常简单的测试,而且无论如何它都是大量数据驱动的,我喜欢这样写。
顺便说一句,这个例子还向您展示了为什么 object[]
而不仅仅是 string
在 IEnumerable: 中可以有很多参数!
我有测试字符串是否为 GUID 的扩展方法。
public static bool IsGuid(this string str)
{
if(str == null)
throw new ArgumentNullException(str, "Argument can not be NULL");
Guid guidFromString;
return Guid.TryParse(str, out guidFromString);
}
我想通过 xUnit 和 Theory 对其进行测试。
对于字符串,它正在工作:
[Theory, InlineData(""), InlineData(" ")]
public void IsGuid_EmptyOrWhiteSpace_ShouldReturnFalse(string str)
{
// Arrange
bool result;
// Act
result = str.IsGuid();
// Assert
Assert.False(result);
}
但是我如何才能为 Guid 数组做到这一点?我需要测试 Guid.Empty' and
Guid.NewGuid`。
这行不通:
[Theory, MemberData(nameof(Guids))]
public void IsGuid_EmptyOrValidGuid_ShouldReturnTrue(string str)
{
// Arrange
bool result;
// Act
result = str.IsGuid();
// Assert
Assert.False(result);
}
public static IEnumerable<string> Guids
{
get
{
yield return Guid.Empty.ToString();
yield return Guid.NewGuid().ToString();
}
}
@编辑 测试失败,因为
System.ArgumentException
Property Guids on ExtensionsLibraryTests.StringExtensions.xUnitStringExtensionsTests yielded an item that is not an object[]
at Xunit.MemberDataAttribute.ConvertDataItem(MethodInfo testMethod, Object item)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at Xunit.Sdk.XunitTheoryTestCaseRunner.<AfterTestCaseStartingAsync>d__7.MoveNext()
您的测试方法目前只有一个参数——字符串——但并非必须如此。如果您的测试方法有 3 个参数怎么办?你怎么把它打包成 IEnumerable<what-here?>
因此,当您使用 xUnit 的 'property data' 功能时,xUnit 要求 属性 的形式为 IEnumerable<object[]>
public static IEnumerable<object[]> Guids
{
get
{
yield return new object[]{ "" };
yield return new object[]{ " " };
}
}
这应该可以解决眼前的问题。但是,我鼓励您尝试这种布局:
[Theory, MemberData(nameof(Guids))]
public void thinkofsomesmartname(bool expectedResult, string text)
{
bool result = text.IsGuid();
Assert.Equal(expectedResult, result);
}
public static IEnumerable<object[]> Guids
{
get
{
yield return new object[]{ false, "" };
yield return new object[]{ false, " " };
yield return new object[]{ true, Guid.NewGuid().ToString() };
}
}
当然,通过数据集传递 'expected result' 有点麻烦,这使得发明测试名称有点困难。您可以创建两个数据集:错误和良好,并制作两种测试方法,一种使用 Assert.False,一种使用 Assert.True.. 但由于它是非常简单的测试,而且无论如何它都是大量数据驱动的,我喜欢这样写。
顺便说一句,这个例子还向您展示了为什么 object[]
而不仅仅是 string
在 IEnumerable: 中可以有很多参数!