捕获异常而不抛出类型

时间:2019-12-18 17:56:26

标签: c# exception xunit

我是xUnit的新手,我正在尝试扩大测试范围。我有一个看起来像这样的类结构:

public class Class1 
{
   public override void Method1() 
   {
      try 
      {
         // some code logic
      } 
      catch (CoreException ex)
      {
         BmpException lex = new BmpException();
         throw lex;
      }
      catch (CodedException ex)
      {
         BmpException lex = new BmpException();
         throw lex;
      }
   }
}

我的xUnit Testing方法看起来像这样:

[Fact]
public void TestMethod()
{
   Class1 SomeClass = new Class1();

   // Works but doesn't affect code coverage ?
   Assert.Throws<BmpException>(() => SomeClass.Method1());

   // Test failed - Expected: CodedException Actual: BmpException
   // Assert.Throws<CodedException>(() => SomeClass.Method1());

   // Test failed - Expected: CoreException Actual: BmpException
   // Assert.Throws<CoreException>(() => SomeClass.Method1());
}

所以我在这里面临的问题是我需要涵盖CoreException和CodedException块的测试。由于Assert.Throws <>捕获了表达式并断言了该类型,因此我找不到解决方法来完成我的测试范围。

任何帮助将不胜感激。谢谢

2 个答案:

答案 0 :(得分:1)

您可以像这样获得引发的异常:

 var ex = Assert.Throws<BmpException>(() => SomeClass.Method1());

 Assert.Equal("test message", ex.Message);

假设BmpException是从System.Exception类继承的。要保留原始异常,您应该在自定义异常BmpException lex = new BmpException(ex);中传递原始异常,这将在InnerException中保留堆栈跟踪。这是包装异常以添加其他信息并保留原始异常的标准方法。这样,您将可以在InnerException上断言。

Assert.Equal(typeof(CoreException), ex.InnerException.GetType());
//Add as many assertion as you like here.

答案 1 :(得分:1)

  

我有一个看起来像这样的类结构:

由于丢失所有相关信息,简单地引发不同的异常通常是非常不好的做法。 至少,您应该wrap the exception

因为您包含所有相关代码

// some code logic

不可能给您一个程序化的答案。基于缺乏信息,唯一可以给出的真实答案是您的测试需要引起某些代码逻辑抛出每种异常类型(CoreException和{{1} }),以增加代码覆盖率。

  

//测试失败-预期:CodedException实际:BmpException

     

// Assert.Throws(()=> SomeClass.Method1());

您永远不能将类型声明为CodedExceptionCoreException,因为它们是Swallowed or Error Hiding。这些异常始终丢失在方法调用中。

  

由于Assert.Throws <>捕获了表达式并断言了类型,所以我找不到解决方法

您必须捕获要抛出的类型:

CodedException

只要您可以为逻辑提供一种通过特定的逻辑编程路径抛出该类型的方式的方式,您就不必关心它到底是什么类型的异常。

例如:

var ex = Assert.Throws<BmpException>(() => SomeClass.Method1());

这具有3的圈复杂度,因为尽管只有一个结果,但存在三种可能的路线。要使此代码具有100%的代码覆盖率,必须通过确保逻辑支持结果来测试以下测试:

public void AnyBodyWantAPeanut(int i)
{
  try 
  {
    if (i == 1) 
      throw new InvalidOperationException("You keep using that word");
    if (i == 2) 
      throw new ArgumentException("I don't think it means");
    throw new ArithmeticException ("What you think it means");
  }
  catch (Exception ex)
  {
    Throw Exception("No more rhymes now I mean it!");
  }
}

相关问题