如何模拟导致异常的事件来测试try / catch块?


14

我了解异常如何工作以及如何在C#中捕获和处理异常,但是我如何模拟可能导致异常的事件以确保正确捕获异常?例如,是否可以在一种可以模拟网络问题,数据库问题等的测试平台上运行应用程序?异常的性质似乎很难重现,因此很难确保您的代码可以应对它们。

尽管我主要使用C#/。NET / Visual Studio开发,但是与其他语言有关的答案或资源可能会很有用。


此MSDN文章中描述了另一种可能的解决方案:使用TestApi进行故障注入测试
Giorgi

Answers:


13

1)如果遵循依赖性注入模型,则可以用模拟代替某些部分的实际实现,该模拟会在需要时抛出异常。但是,这将需要您以特定方式初步设计应用程序或对其进行完全重新设计。

喜欢:

public class SqlUsersRepository : IUsersRepository
{
    public void RegisterNewUser (User newUser)
    {
        throw new SqlException ("Connection timeout");
    }
}

但是,在这里我们会遇到这样的问题,即消费者代码不应该处理具体的实现异常。

2)另一种方法是用自定义包装器替换某些方法调用。

代替:

FileStream fs = File.OpenRead (path);

你用:

FileStream fs = File.OpenRead_Test (path);

通过提供自定义扩展方法(只是个简单的主意):

public static FileStream OpenRead_Test (this System.IO.File file, string path)
{
    throw new FileNotFoundException ();
}

3

您需要查看模拟框架。

通过这些,您可以使用依赖注入来调用伪数据库(例如),而不是真实的数据库。这意味着您可以完全控制每次调用返回的内容。

然后,您建立一个测试,该测试在被调用时仅引发所需的异常:

public void Test1()
{
    throw new NullArgumentException();
}

当您的代码正确处理此问题时,您的测试通过。


3

模拟和注入只能使您步入正轨,并且在某些情况下需要对方法进行重大更改。

如果您不想重新设计应用程序以适合测试框架,那么您真正需要的是为错误准备的主机或环境。有许多方法可以模拟网络中断所造成的网络中断(甚至Microsoft测试工具在Web测试领域中也很少使用)。我将机器放置在可以被篡改以与数据库集配合以更改错误的脚本和更改数据库所产生的错误的脚本一起更改模拟的机器上,获得了最大的成功。

即使这样,如果您在硬件上走得足够快或足够远,也会出现诸如并发问题和延迟写入失败之类的错误,您几乎无法模拟。有时,您必须使它们成为现实,而其他时候,您只需要在没有安全网的情况下工作即可。


同意-在某些情况下,例如,您无法承受发布代码中依赖项注入的开销。这不是每天的问题,但是有可能发生。
Steve314 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.