【问题标题】:NUNIT 3 and ExpectedExceptionNUNIT 3 和 ExpectedException
【发布时间】:2018-02-16 11:58:41
【问题描述】:

我想从 NUNIT 2.x 升级到 3.x,但我有类似的测试

[TestCase("12345", ExpectedResult = "SUCCESS")]
[TestCase("invalidkey", ExpectedException = typeof(ArgumentException))]
[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
public string ReturnsStatus(string filePath)
{
    // Arrange

    // Act
    Tuple<string, string> result = service.Create(filePath);

    // Assert
    return result.Item1;
}

如何重写这种测试? NUNIT 3.x 没有 ExpectedException,这是我重构的原因。我不想分成 3 个测试。 谢谢。

【问题讨论】:

标签: c# nunit


【解决方案1】:

如您所见,NUnit 3 删除了ExpectedExceptionAttribute 以及TestCaseAttributeTestCaseData 上的相关属性。

这是在经过大量社区讨论后完成的,达成的共识还不到 100%,但大多数人都认识到在整个测试级别广泛检测异常构成了一种反模式。您的示例实际上代表了一种并非如此糟糕的做法的情况:只有一个语句的测试方法。不幸的是,您也会受到更改的影响。

两个建议: 1. 对“快乐路径”和错误进行单独测试。 2.使用Assert.ThrowsAssert.That(..., Throws...)进行错误测试。

【讨论】:

    【解决方案2】:

    这是一个老问题,但无论如何......

    如前所述,ExpectedException 被认为是一种不好的做法,因为您无法确定测试的确切部分引发了异常(在您的代码中,它可以是 Create() 或 get_Item1())。

    但是,您不需要为每个案例编写单独的测试方法。在大多数情况下(在您的示例中),拆分两个测试就足够了:阳性和阴性。正例可以保持不变。负例可以使用预期异常的类型作为参数,这样:

    [TestCase("",  typeof(ArgumentException))]
    [TestCase(null, typeof(ArgumentNullException))]
    public void ReturnStatusInvalidArgument(string filePath, Type expectedException)
    {
        Assert.Throws(expectedException, () => Method(filePath));
    }
    

    或者如果你更喜欢“ExpectedResult”风格,那么你可以使用以下

        [TestCase("", ExpectedResult = typeof(ArgumentException))]
        [TestCase(null, ExpectedResult = typeof(ArgumentNullException))]
        public Type ReturnStatusInvalidArgument(string filePath)
        {
            return Assert.Catch(() => Method(filePath)).GetType();
        }
    

    【讨论】:

    • 是否有可能匹配从异常返回的消息?在我的 scneraio 中,我有相同的异常,但有不同的消息
    • 我已经通过获取异常的消息属性对其进行排序,然后匹配不同消息的预期结果。我只是想知道这是一种仪式吗?
    • Assert.Catch(第二种方法)返回适当的异常实例。而不是 GetType() 你可以得到 Message
    【解决方案3】:

    我认为“一种方法==一种测试”是最佳实践:

    [TestCase("12345", ExpectedResult = "SUCCESS")]
    public string ReturnStatusTest_SUCCESS()
    {
        return ReturnsStatus("12345");
    }
    [TestCase("invalidkey", ExpectedException = typeof(ArgumentException))]
    public string ReturnStatusTest_SUCCESS()
    {
        return ReturnsStatus("invalidkey");
    }
    [TestCase(null, ExpectedException = typeof(ArgumentNullException))]
    public string ReturnStatusTest_SUCCESS()
    {
        return ReturnsStatus(null);
    }
    
    public string ReturnsStatus(string filePath)
    {
        // Arrange
    
        // Act
        Tuple<string, string> result = service.Create(filePath);
    
        // Assert
        return result.Item1;
    }
    

    【讨论】:

    • NUNIT 3.x 没有 ExpectedException,这是我重构的原因:)
    • 在 3.X 中,您必须使用 Values(1,2,3) 作为参数并自己定义预期结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 2013-02-07
    • 2016-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多