C# 防止捕获NUnit断言异常?

C# 防止捕获NUnit断言异常?,c#,unit-testing,exception,nunit,assert,C#,Unit Testing,Exception,Nunit,Assert,我现在正在做一个项目,需要与包含异常的代码进行交互操作。特别是,我正在编写NUnit单元测试。在某些地方,我希望在作为委托传递的代码中嵌入断言,作为模拟特定行为的一部分。我遇到的问题是AssertionException被调用委托的代码吞没,这意味着测试通过,即使测试断言失败 有没有办法通知NUnit测试应该失败,而不能通过捕获断言异常来规避?我不能修改包含异常的代码,因为我没有完全的所有权,并且它已经在半成品中使用。我希望有一个干净的方法来实现这一点 我想到的最好的办法是: priva

我现在正在做一个项目,需要与包含异常的代码进行交互操作。特别是,我正在编写NUnit单元测试。在某些地方,我希望在作为委托传递的代码中嵌入断言,作为模拟特定行为的一部分。我遇到的问题是AssertionException被调用委托的代码吞没,这意味着测试通过,即使测试断言失败

有没有办法通知NUnit测试应该失败,而不能通过捕获断言异常来规避?我不能修改包含异常的代码,因为我没有完全的所有权,并且它已经在半成品中使用。我希望有一个干净的方法来实现这一点

我想到的最好的办法是:

    private static string _assertionFailure;
    public static void AssertWrapper(Action action)
    {
        try
        {
            action();
        }
        catch (AssertionException ex)
        {
            _assertionFailure = ex.Message;
            throw;
        }
    }

    [Test]
    [ExpectedException(typeof(AssertionException))]
    public void TestDefeatSwallowing()
    {
        Action failure = () => AssertWrapper(() => Assert.Fail("This is a failure"));

        EvilSwallowingMethod(failure);

        if (_assertionFailure != null)
            Assert.Fail(_assertionFailure);
    }

    private void EvilSwallowingMethod(Action action)
    {
        try
        {
            action();
        }
        catch
        {
        }
    }

它是有效的,但它很难看。我必须包装每个断言调用,并且在每个测试结束时必须检查断言是否被吞没。

那么您是这样做的?(这是使用Moq语法)


不完全相关-您是否将此代码吞噬异常这一事实推到了链的上游?半成品代码应该更容易更改(当然,这取决于具体情况)。相关-这看起来是一个非常聪明的方法。你必须围绕一个极其丑陋的模式工作——这很难做到干净。@arootbeer,我的团队意识到这是一个问题,但这是一个非常系统化的问题,并且与最终用户认为“崩溃”是系统能做的最糟糕的事情联系在一起。有人开玩笑地建议,可以将代码更改为仅在晚上7点到早上7点之间吞噬异常。哇-我不会再进一步了:)您正在测试的所有方法都接受动作作为参数吗?我同意@arootbeer-修复这一点(并解决它)不会变得更容易。当它在生产中吞下IOException而没有保存任何内容时会发生什么?放入一个全局异常处理程序,该处理程序记录详细信息并为用户提供一个友好的对话框。此外,考虑用Exchange断言替换ExpEdExtPositError:@ AROOTBLE,它比我给出的示例稍微复杂一些。断言被嵌入到模拟接口调用的回调中,因为我试图感知我正在测试的代码何时调用特定的服务,以及它是否正确使用服务调用。这相当于在接口的方法中传递带有测试断言的接口的测试实现。是使用服务的代码吞咽异常,包括AssertionException。生产代码确实对(大多数)捕获位置进行了日志记录,但它仍在防止异常传播。吞咽发生在我所依赖的代码中,但这是实现我所编写和正在测试的代码逻辑的核心,因此不应该嘲笑它。我想我可以创建一个类的副本,它不会吞下异常,并且只将该副本用于我的代码,但这会产生其他政治和维护问题。
var dependency1 = new Mock<IDependency1>();
dependency1.Setup(d => d.CalledMethod([Args])
    .Callback(TestOutArgsAndPossiblyThrow);

var objectUnderTest = new TestedObject(dependency1.Object);
objectUnderTest.MethodThatCallsIDependency1dotCalledMethod();
TEST -> TESTED CODE -> SWALLOWING CODE -> THROWING MOCK