【问题标题】:xUnit theory guids as parametrxUnit 理论指南作为参数
【发布时间】:2017-07-31 16:12:33
【问题描述】:

我有测试字符串是否为 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' andGuid.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()

【问题讨论】:

  • 嘿..也许只是yield return Guid.NewGuid().ToString();返回了一个有效的GUID,而您的测试有Assert.False?要让这段代码与前一段代码 (InlineData(""), InlineData(" ")) 相同,您应该使用 yield return ""; yield return " "; 而不是有效的 Guid 字符串..
  • 固定 AAA 部分 :)
  • 可能重复:stackoverflow.com/questions/22093843/…(抱歉,我不能重复投票,因为我撤消了之前的“不清楚”投票..)

标签: c# xunit


【解决方案1】:

您的测试方法目前只有一个参数 - 字符串 - 但不一定是这种情况。如果您的测试方法有 3 个参数怎么办?你怎么把它打包成IEnumerable&lt;what-here?&gt;

因此,当您使用 xUnit 的“属性数据”功能时,xUnit 要求该属性的格式为 IEnumerable&lt;object[]&gt;

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.. 但由于它是非常简单的测试,而且无论如何它都是数据驱动的,所以我喜欢写就这样吧。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    相关资源
    最近更新 更多