【问题标题】:Correct usage of Theory in xUnit在 xUnit 中正确使用 Theory
【发布时间】:2016-06-06 02:41:45
【问题描述】:

我一直在阅读有关 xunit 的内容,但我对如何使用 Theory 感到有些困惑。

假设我有这个测试:

[Theory]
[InlineData("")]
[InlineData("anything")]
public void AddItem_NoName_ThrowsNoNameException(string name)
{
    // Arrange.
    ItemService itemService = new ItemService();
    Item item = new Item();
    item.Name = name;

    // Act.
    Exception ex = Record.Exception(() => itemService.AddItem(item));

    // Assert.
    Assert.NotNull(ex);
    Assert.IsType<NoNameException>(ex);
}

以及被测方法:

public void AddItem(Item item)
{
    if (item.Name == "")
        throw new NoNameException();
    _DAL.AddItem(item);
}

所以这会创建两个单元测试:一个传递一个空字符串 ("") 的参数,一个传递一个单词“anything”。所以第一个(空字符串)通过了,因为我们有代码检查 item.Name 是否为空字符串,抛出异常。然而,第二个失败了,因为单元测试中的 Assert.NotNull(ex) 将是错误的。但是,如果您查看 AddItem 方法,则该方法编码正确,所以我想看到两个测试都通过了。

也许我通过单元测试实现的方式是错误的,但我想要发生或我认为在这种情况下应该发生的是两个测试都应该通过,因为被测方法是正确的(基于规则)。我该怎么做?

更新:

好的,我已经通过执行下面的代码设法使这两个都通过了。但是,我认为这是不正确的,有条件断言。仍然需要帮助。

[Theory]
[InlineData("", false)]
[InlineData("anything", true)]
public void AddItem_NoName_ThrowsNoNameException(string name, isValid)
{
    // Arrange.
    ItemService itemService = new ItemService();
    Item item = new Item();
    item.Name = name;

    // Act.
    Exception ex = Record.Exception(() => itemService.AddItem(item));

    // Assert.
    if (!isValid)
    {
        Assert.NotNull(ex);
        Assert.IsType<NoNameException>(ex);
    }
    else
    {
        Assert.Null(ex);
    }
}

【问题讨论】:

  • 文档不清楚怎么办? xunit.github.io/docs/getting-started-desktop
  • @Daniel Mann:他们的例子很清楚,但我不这么认为。
  • 我同意你关于没有条件断言的说法。这应该分为两个单独的测试。一个验证异常被抛出空名称,一个验证快乐路径。当namenull 时,您可以在现有理论中添加一个额外的案例,因为它应该包含与空字符串相同的测试代码。

标签: .net unit-testing xunit


【解决方案1】:

这是两个不同的测试用例,应该编写单独的测试。 Theory应该在测试代码相同的情况下使用。

[Theory]
[InlineData("")]
[InlineData(null)] // will fail based on your impl, just used for example
public void AddItem_NoName_ThrowsNoNameException(string name)
{
    // Arrange
    ItemService itemService = new ItemService();
    Item item = new Item();
    item.Name = name;

    // Act & Assert
    Assert.Throws<NoNameException>(() => itemService.AddItem(item));
}


[Fact]
public void AddItem_WithName_DoesXYZ()
{
    // Arrange
    ItemService itemService = new ItemService();
    Item item = new Item();
    item.Name = "anything";

    // Act
    itemService.AddItem(item);

    // Assert
    # verify item was added to db 
}

【讨论】:

  • 好吧,这就是让我感到困惑的地方。在此链接xunit.github.io/docs/getting-started-desktop 中,他们说“理论是仅对特定数据集有效的测试。”。所以我在想你可以在 Theory 中传递一些错误和正确的值(如该页面中的示例)。如果是这种情况,我们是否将错误的数据测试留在我们的测试列表中? Theory 允许错误数据的目的是什么?
  • 我认为这只是一种误解。您将希望在应该通过的理论案例中使用数据。我没有理由传递错误的数据,我认为这会导致测试失败,这与目的不符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 2021-11-30
相关资源
最近更新 更多