xUnit theory guids as parametr

时间:2017-03-10 10:38:53

标签: c# xunit

我有扩展方法,用于测试字符串是否为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);
}

但我如何才能为Guids阵列做到这一点?我需要测试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();
    }
}

@Edit 测试失败,因为

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()

1 个答案:

答案 0 :(得分:2)

您的测试方法目前只有一个参数 - 字符串 - 但并非必须如此。如果您的测试方法有3个参数怎么办?如何将其打包成IEnumerable<what-here?>

出于这个原因,当您使用&#39;属性数据&#39; xUnit的特性,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() };
    }
}

当然,通过“预期结果”会有点骇人听闻。通过数据集,这使得发明测试名称有点困难。您可以创建两个数据集:错误和良好,并使用Assert.False制作两个测试方法,使用Assert.True制作一个测试方法..但由于它是非常简单的测试,因为它无论如何都是大量数据驱动的,我喜欢这样写。

顺便说一下,这个例子还向您展示了为什么object[]而不仅仅是IEnumerable中的string:可以有很多参数!