忽略xUnit.net中的异常

时间:2010-12-13 17:15:09

标签: c# .net assert xunit

我有些情况下我不关心抛出什么异常(只要抛出一些异常)。不幸的是,

Assert.Throws<Exception>(someDelegate);
除非确实抛出了Exception的实例(因此不是派生类的实例),否则

不会通过。我知道我可以通过

获得我想要的行为
Exception exception = Record.Exception(someDelegate);
Assert.NotNull(exception);

但它没有正确的读数。我是否在xUnit中缺少具有我想要的行为的东西?这是两个测试,表明我的意思:

[Fact]
public void Throws_exception_and_passes() {
    Exception exception = Record.Exception(
        () => { throw new InvalidOperationException(); }
    );
    Assert.NotNull(exception);
}

[Fact]
public void Throws_exception_and_fails() {
    Assert.Throws<Exception>(
        () => { throw new InvalidOperationException(); }
    );
}

6 个答案:

答案 0 :(得分:7)

根据这里的文件:

http://xunit.codeplex.com/wikipage?title=HowToUse&referringTitle=Home

您必须指定要抛出的异常类型。一般来说,这是一种很好的做法。您应该能够预测测试会引发什么类型的异常。您应该能够以允许您预测此方法的方式设计方法和测试。

有很多方法可以解决这个问题,比如试一试自己,但是你应该考虑改变你的设计。

答案 1 :(得分:5)

在此问题时它不存在,但现在可以使用struct array_deck *add_to_list(uint8_t *data, bool add_to_end) { ... struct array_deck *ptr = (struct array_deck*)malloc(sizeof(struct array_deck)); if(NULL == ptr) return NULL; ptr->val = malloc(16*sizeof(uint8_t)); memcpy(ptr->val, data, 16*sizeof(uint8_t)); ptr->next = NULL; ... } 来测试从Assert.ThrowsAny<Exception>派生的任何异常(因此任何异常)以及变体等作为Exception,它将测试从Assert.ThrowsAny<ArgumentException>派生的任何异常,等等。

答案 2 :(得分:2)

如果你想自己做Custom Assertion,xUnit将不会阻挡你的行为,如:

public static bool Throws<T>(this Action action, bool discardExceptions = false) 
    where T : Exception
{
    try
    {
        action.Invoke();
    }
    catch (T)
    {
        return true;
    }
    catch (Exception)
    {
        if (discardExceptions)
        {
            return false;
        }
        throw;
    }
    return false;
}

或者:

public static bool Throws(this Action action)
{
    try
    {
        action.Invoke();
    }
    catch (Exception)
    {
       return true;
    }
    return false;
}

答案 3 :(得分:2)

正如您已确定Assert.Throws<T>是否不适合该帐单,xUnit中唯一的OOTB事项就是使用Record.Exception

正如您所确定的那样,做'Assert抛出任何东西'的主要方法是做

Assert.NotNull( Record.Exception( lambda ))

看看它 - 不漂亮。这很可能是设计上的; xUnit.net中很少有事情是偶然的(与经过仔细考虑的自以为是的设计相反)。

Record.Exception返回结果的原因(如果您使用的是F#,则必须|> ignore清除该值)。你应该始终能够Assert关于正在发生的异常的性质,以便你随着时间的推移改变代码时代码中的实际问题不会被忽略,这就是原因对于所有这些测试的东西,首先。也许这可能采取

的形式
var exception = Record.Exception( sut.Something );
Assert.True( typeof(SomeException).IsAssignableFrom( exception ) );

考虑到这一点,Assert.NotNull()更安全,但仍然感觉不对。现在是时候了,正如GOOS中讨论的那样,听取您的测试(对于一个固定的测试框架,您的测试框架)。


然而,你问题中最大的问题是,在真实测试的真实例子中,总有一种方法可以让你的界面更清晰或以另一种方式表达你的期望,所以真正的答案是Mu

答案 4 :(得分:1)

我只是看着xUnit.net source,这是罪魁祸首:

private static Exception Throws(Type exceptionType, Exception exception)
{
    Guard.ArgumentNotNull("exceptionType", exceptionType);

    if (exception == null)
        throw new ThrowsException(exceptionType);

    if (!exceptionType.Equals(exception.GetType()))
        throw new ThrowsException(exceptionType, exception);

    return exception;
}

如果应用此更改,将解决您的问题:

if(!exceptionType.Equals(exception.GetType()))

为:

if(!exception.GetType().IsAssignableTo(exceptionType))

您可以提出提交补丁吗?

答案 5 :(得分:0)

    public static void SuppressException<TSut>(this TSut value, Action<TSut> action) where TSut : class
    {
        try
        {
            action.Invoke(value);
        }
        catch (Exception)
        {
            //do nothing
        }
    }