繁体   English   中英

在终结器中抛出异常时,Visual Studio 测试资源管理器未完成运行 NUnit 测试

[英]Visual Studio Test Explorer doesn't finish running NUnit tests when exception in finalizer is thrown

我的NUnit测试需要运行来自第三方 dll 的一些代码。该代码可能会在垃圾回收期间抛出异常。 特别是在Finalize方法期间。 当发生此类异常时,Visual Studio Test Explorer/Runner 将停止运行测试套件,因此我只剩下未运行的测试。

因为只有在测试线程完成之前调用垃圾收集才会发生这种情况,所以这是间歇性的,但如果我添加,我可以让它始终可重现以进行测试

GC.Collect();
GC.WaitForPendingFinalizers();

我无法更改第三方源代码。

下面是一个 class,它可以通过 .Net 6 Nunit 测试项目显示此行为。 如果单独运行,您会注意到 Test2 如何通过,但如果运行整个夹具则永远不会运行。

namespace TestProject
{
   public class Tests
   {
      [SetUp]
      public void Setup()
      {
      }

      [Test]
      public void Test1()
      {
         var x = new BrokenFinalizer();
         GC.Collect();
         GC.WaitForPendingFinalizers();
      }

      [Test]
      public void Test2()
      {
         var x = new BrokenFinalizer();
         GC.Collect();
         GC.WaitForPendingFinalizers();
      }
   }

   public class BrokenFinalizer
   {
      public BrokenFinalizer() { }

      ~BrokenFinalizer() 
      {
         throw new Exception();
      }
   }
}

我怎样才能强制 Visual Studio Text Explorer/Runner 完成项目中所有测试的运行,即使它需要处理这个“Broken Finalizer”案例?

不幸的是,我能找到的最佳解决方案是对存在此问题的第三方对象使用GC.SuppressFinalize

因为我可能仍然想运行Finalizer器并在运行时中止我写了这个 class 来让我控制终结器何时被抑制

public class FinalizerControlled
{ 
   public FinalizerControlled(object value, bool forceSuppress = false)
   {
      if (IsTesting() || forceSuppress)
      {
         GC.SuppressFinalize(value);
      }
   }

   private static bool IsTesting()
   {
      ...
   }
}

然后对于导致单元测试中止的EditOperation object 的所有实例,我添加以下行

var _ = new FinalizerControlled(editOperation);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM