我想声明在某个类中抛出异常

时间:2013-07-21 22:24:47

标签: c# unit-testing

我正在为我的客户端/服务器设置构建一个TestProject。我想验证测试在某个执行块内是否失败(没有客户端要发送,因此服务器的Send()方法将抛出异常)。因为我不想让测试启动客户端和服务器并让它们进行通信(我在一台机器上遇到了问题。)

如果代码到达此行,则意味着程序的执行流程只能在另一个测试的职责范围内失败。除了对抛出的异常的stacktrace进行子字符串检查之外,还有更简单的方法吗?我觉得这种方法不是很容易扩展,如果类名改变,就需要经常注意。

有没有办法甚至不涉及手动检查异常的堆栈跟踪?

3 个答案:

答案 0 :(得分:2)

如果您使用的是NUnit

不使用DataAnnotations

[Test]
public void Test_XXXXXXX
{
    var yourClass = new YourClass(); 
    Assert.That(()=>yourClass.Method(),
                    .Throws.Exception
                    .TypeOf<TypeOfYourException>
                    .With.Property("Message")
                    .EqualTo("the message you are expecting goes here")
               );
}

使用DataAnnotations

[Test]
[ExpectedException(typeof(ExceptionType), ExpectedMessage="your message goes here!")]
public void Test_XXXXXXX
{
      var yourClass = new YourClass();     
      // Call your method in a way that it will fail
      yourClass.YourMethod();
}

答案 1 :(得分:0)

除了特定于该类的异常外,该类中的异常是否有任何独特之处?

如果邮件可以识别,您可以像其他答案所示进行测试,或者如果您不使用NUnit,则可以测试它:

try {    
   myMethod();
   Assert.Fail("Expected exception to be thrown."); 

} catch (MyException ex) {    
   Assert.Equals("My Exception Message", ex.Message, "Exception message was formatted incorrectly.");

} catch (Exception) {    
   Assert.Fail("An exception was thrown, but of the wrong type.");    
}

答案 2 :(得分:0)

当您对某个类进行单元测试时,有两个异常来源:

  1. 您正在测试的类可以抛出异常
  2. 类的依赖可以抛出异常
  3. 在第二种情况下,您通常要么处理异常,要么将其包装在更高级别的异常中并将其抛给调用者。那么,如何测试所有这些案例呢?

    正在测试的系统引发异常

    E.g。在传递给方法的错误参数的情况下抛出异常(NUnit样本):

    StockService service = new StockService();
    Assert.Throws<ArgumentNullException>(() => service.Connect(null));
    

    您不需要检查堆栈跟踪,因为它是一个应该抛出异常的被测试类。

    依赖关系抛出异常并处理它

    当你的类有依赖关系时,你应该模拟依赖关系,以便单独测试你的类。因此,当您的类与它们交互时,很容易设置模拟以抛出异常。考虑如果未找到配置文件(Moq示例),服务应在默认设置下运行的情况:

    var configMock = new Mock<IStockServiceConfig>();
    configMock.Setup(c => c.Load()).Throws<FileNotFoundException>();
    
    StockService service = new StockService(configMock.Object);
    service.Connect("google");
    
    configMock.VerifyAll();
    Assert.That(service.Port, Is.EqualTo(80));
    

    如果您不尝试加载配置,或者如果您不处理FileNotFoundException,则此测试将失败。

    异常堆栈跟踪在这里并不重要 - 我们不关心我们的直接依赖引发异常,还是其他类内部依赖。 实际上我们不知道该类是否存在 - 我们只与直接依赖进行交互。我们应该只关心依赖可以抛出异常的事实,我们可以处理它。

    依赖关系抛出异常并将其包装

    最后一个案例 - 将异常包装在更高级别的东西中。考虑前面的示例,但配置非常重要,如果没有配置文件,则无法启动。在这种情况下,您将FileNotFoundException包装成更具体业务的内容,这在更高级别的应用程序中是有意义的。例如。 StockServiceInitializationException

    var configMock = new Mock<IStockServiceConfig>();
    configMock.Setup(c => c.Load()).Throws<FileNotFoundException>();
    
    StockService service = new StockService(configMock.Object);
    Assert.Throws<StockServiceInitializationException>(_ => service.Connect("bing"));
    
    configMock.VerifyAll();
    

    正如您所看到的,我们也不关心异常的堆栈跟踪,这会引发我们的依赖。它也可能是更低级异常的一些包装。预期的服务行为 - 如果找不到配置,则抛出高级初始化异常。我们正在验证这种行为。

相关问题