C# 努尼特';s TestCustomException不';我不关心异常类型

C# 努尼特';s TestCustomException不';我不关心异常类型,c#,.net,exception,nunit,C#,.net,Exception,Nunit,如果我想测试某个方法是否抛出特定类型的异常,NUnit的ExpectedException属性不关心实际的类型;如果我在方法调用之前抛出一般异常,则测试通过: [Test, ExpectedException(typeof(TestCustomException))] public void FirstOnEmptyEnumerable() { throw new Exception(); // with this, the test should fai

如果我想测试某个方法是否抛出特定类型的异常,NUnit的ExpectedException属性不关心实际的类型;如果我在方法调用之前抛出一般异常,则测试通过:

    [Test, ExpectedException(typeof(TestCustomException))]
    public void FirstOnEmptyEnumerable()
    {
        throw new Exception(); // with this, the test should fail, but it doesn't
        this.emptyEnumerable.First(new TestCustomException());
    }
如果我想检查测试是否抛出了完全相同的异常类型,我必须执行如下手动操作:

    [Test]
    public void FirstOnEmptyEnumerable()
    {
        try
        {
            throw new Exception();  // now the test fails correctly.
            this.emptyEnumerable.First(new TestCustomException());
        }
        catch (TestCustomException)
        {
            return;
        }

        Assert.Fail("Exception not thrown.");
    }

我遗漏了什么吗?

我总是测试异常的字符串表示形式,例如:

[Test, ExpectedException("Your.Namespace.TestCustomException")]
public void FirstOnEmptyEnumerable()
{
    throw new Exception(); // with this, the test should fail, but it doesn't
    this.emptyEnumerable.First(new TestCustomException());
}

这对我来说似乎很好。

我从未使用过ExpectedException,所以我没有任何经验可以分享。一个选项是断言它直接在测试内部抛出。大概是这样的:

[Test]
public void FirstOnEmptyEnumerable()
{
    Assert.Throws<TestCustomException>(() => this.emptyEnumerable.First(new TestCustomException()));
}
[测试]
public void FirstOnEmptyEnumerable()
{
Assert.Throws(()=>this.emptyEnumerable.First(新的TestCustomException());
}

我发现这种方法更具可读性,因为您可以在预期发生异常的地方测试异常,而不是说“在这个函数中的某个地方,除了要抛出的异常之外”

如果要使用ExpectedException(字符串)签名,最佳做法是使用typeof(Exception).Name和typeof(Exception).Namespace

通常不建议使用这样的字符串。如果更改异常的名称,测试将无效。幸运的是,在这种情况下,测试将开始失败,因此您可能会看到这一点,并在测试中更新ExceptedException。尽管如此,经历这一切还是很痛苦。。使用字符串的优点是,您不需要引用包含异常定义的程序集。谢谢您提供的信息。如果字符串方式不被推荐,并且
typeof()
方式对OP不起作用,您推荐什么方式?我发布了一个答案,说明我将如何做。。如果您对字符串定义感到满意,请继续使用它,但请注意它可能有一天会影响您。这是一个好主意,我认为它适合大多数情况,但我尽量避免捕获断言中的异常作为测试。我喜欢这两者之间的区别(例外和结果),而且我觉得这使我的测试(两种类型的测试)变得复杂。我想这是一个偏好的问题。我更喜欢这种方法。谢谢杰克逊·波普@Neowizard:emptyEnumerable。首先是一个Linq风格的帮助程序扩展方法,如果序列为空,它会抛出一个自定义异常,因此,在这种情况下,测试它是否抛出正确的异常是有意义的好主意,NUnit应该加上:)