防止捕获NUnit AssertionException?

时间:2010-09-14 21:06:04

标签: c# unit-testing exception nunit assert

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

有没有办法通知NUnit测试失败,无法通过捕获AssertionException来规避?我不能修改吞下异常的代码,因为我没有完全的所有权,而且它已经在半生产中使用了。我希望有一个干净的方法来实现这一目标。

我提出的最好的是这样的:

    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
        {
        }
    }

它有效,但它非常难看。我必须包装每个Assert调用,并且我必须在每次测试结束时检查是否吞下了一个断言。

1 个答案:

答案 0 :(得分:2)

所以你正在做这样的事情? (这是使用Moq语法)

var dependency1 = new Mock<IDependency1>();
dependency1.Setup(d => d.CalledMethod([Args])
    .Callback(TestOutArgsAndPossiblyThrow);

var objectUnderTest = new TestedObject(dependency1.Object);
objectUnderTest.MethodThatCallsIDependency1dotCalledMethod();

您的TestOutArgsAndPossiblyThrow课程已封装AssertWrapper吗?

除非那样离开,否则我说你做得恰到好处。您已执行重新进入测试的位置,您可以记录对依赖项的调用状态。无论是通过捕获异常并分析它们还是直接检查方法参数的值,您都必须完成这项工作。如果你在黑匣子内吞下异常,你将不得不在他们回到黑匣子之前对它们进行监控。

我仍然说你通过适当的日志记录和通知会更好(你不必通知最终用户)。要@ThenWill的观点 - 当IOException或数据库不可用时,你做什么

讨论编辑

你的情景结构是这样的吗?

TEST -> TESTED CODE -> SWALLOWING CODE -> THROWING MOCK