如何防止因模拟对象的未设置期望引起的吞咽异常?

时间:2011-03-04 06:59:03

标签: c# .net unit-testing exception-handling mstest

我正在寻找一种方法来修改catch块,具体取决于它是否在单元测试运行期间执行。目的基本上是检测/设置被吞下的模拟期望,因为catch不会重新抛出。

我正在使用MSTest。

一个显而易见的事情是使用预处理器,但我认为它不起作用。特别是如果要使用DEBUG定义。应该有一种简单的方法来检测它,不应该吗?我一定是在找错了,因为我找不到太多的信息。

try {...}
catch(Exception)
{
    Log(...);
#if DEBUG
        throw;
#endif

}

答案:将try的主体提取到另一个方法中并进行测试。由Jon和Ritch提供。请参阅Jon的回答下的讨论。虽然感谢大家的贡献。

3 个答案:

答案 0 :(得分:3)

如果要更改异常处理,如何测试异常处理?测试改变的行为不会测试如果没有改变行为会发生什么。

希望您的模拟有其他方法可以让您在测试结束时验证期望,这样您就可以避免以这种方式忽略异常 - 并且您应该测试您的日志和修复确实 在你想要的时候发生。 (测试日志记录很繁琐而且很少值得,但可能Fix会做一些重要的事情。)你还应该测试异常不是重新抛出,如果这是设计的一部分。

(另一方面,抓住ArgumentException 通常一个糟糕的迹象开始。但也许在这种情况下,这是由于你必须使用设计不佳的库。)

编辑:就像一个想法,如果您将能够测试日志和修复,这意味着您必须能够检查它们是否被调用。如果您期望抛出异常,您应该能够验证他们未被调用。如果是的话,你已经有效地证明了抛出异常。

答案 1 :(得分:3)

我仍然支持我在评论中所说的内容,Jon似乎同意我的看法:即时更改您的代码只是为了测试一种节拍测试的目的。

如果您需要“注释掉”某些异常处理以使测试可行,则可能表明您在代码中过早捕获异常。

也许你应该重构你的代码,以便它不会被修改用于测试,然后设计进一步测试调用堆栈以验证异常是按照你的预期处理的。

答案 2 :(得分:0)

“#IF DEBUG”应谨慎使用。您告诉测试的代码在测试期间采取不同的行为,从而使测试非常接近无用。 请改为捕获特定的异常类型。不应该只是默默地抓住例外 - 他们必须留下某种痕迹。所以,要么你抛出一个异常,要么做一些可以被outsders检测到的东西 - 包括你的测试。

我的建议是识别您的代码将遇到的不同类型的异常,并为每个异常制作一个catch块。请记住,您可以创建自己的异常类型:

    private class MyException: Exception 
    {
    }

这可用于组织与代码逻辑对应的组中的exeptions。

如果您的程序不是Windows或Web服务,我建议您不要捕获基本的“异常”类型。这是基于这样的理念:如果程序遇到意外行为,应该感觉清醒。在这种情况下,不应将异常视为意外(即,在使用数据库时,应该预期偶尔会出现连接问题,超时,用户问题等)。