c# - 为什么启用 JetBrains dotCover 会导致 NUnit 测试失败?

标签 c# garbage-collection nunit teamcity dotcover

我编写了一些如下所示的代码,以对 C# 终结器方法的实现进行单元测试。

在 TeamCity 版本 2017.1.3 中,我使用带有 NUnit 运行器类型的构建步骤来使用 NUnit.ConsoleRunner.3.7.0 运行此测试。

如果我启用 JetBrains dotCover .NET 覆盖工具,测试将失败。

如果我禁用 .NET Coverage,测试就会通过。

dotCover 可能会做什么来影响测试结果?

using System;
using System.Threading;
using NUnit.Framework;
using Telerik.JustMock;

namespace MyNamespace
{
    public interface IWin32Api
    {
        void FreeResource();
    }

    public class Disposable
    {
        private readonly IWin32Api _win32;

        public Disposable(IWin32Api win32)
        {
            _win32 = win32;
        }

        ~Disposable()
        {
            _win32.FreeResource();
        }
    }

    [TestFixture]
    public class TestFixture
    {
        [Test]
        public void Test()
        {
            using (var signal = new ManualResetEvent(false))
            {
                var win32 = Mock.Create<IWin32Api>();

                Mock.Arrange(() => win32.FreeResource())
                    .DoInstead(() => { signal.Set(); });

                var subjectUnderTest = new Disposable(win32);

                subjectUnderTest = null;

                GC.Collect();

                if (!signal.WaitOne(TimeSpan.FromMinutes(1)))
                {
                    Assert.Fail("IWin32Api.FreeResource never called");
                }
            }
        }
    }
}

最佳答案

我仍然不明白发生了什么,但我能够通过使用 immediately-invoked function expression 解决问题并通过测试。 .

测试方法现在看起来像这样:

[Test]
public void Test()
{
    using (var signal = new ManualResetEvent(false))
    {
        var win32 = Mock.Create<IWin32Api>();

        Mock.Arrange(() => win32.FreeResource())
            .DoInstead(() => { signal.Set(); });

        new Action(() => { new Disposable(win32); })();

        GC.Collect();

        GC.WaitForPendingFinalizers();

        if (!signal.WaitOne(TimeSpan.FromMinutes(1)))
        {
            Assert.Fail("IWin32Api.FreeResource never called");
        }
    }
}

如果我将 new Action(() => { new Disposable(win32); })(); 替换为 new Disposable(win32); 或使用 var d = new Disposable(win32); d = null;

关于c# - 为什么启用 JetBrains dotCover 会导致 NUnit 测试失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45891284/

相关文章:

java - InputStreams 被 GCed

c# - C#自动创建对象母类

c# - Regex.Match 简单数组

c# - 将 foreach 循环转换为 LINQ 查询会破坏代码

Android:当 Activity 被销毁时,设置引用 null 有什么好处吗?

python - Python GC 也会关闭文件吗?

c# - 运行我的 c# Selenium WebDriver 代码的 NUnit 错误

c# - Moq插入/更新新对象初始化

c# - 服务安装程序类可以在不同的程序集中运行吗?

c# - 在 C# 中编写多播委托(delegate) - 我应该使用运算符还是 Action.Combine?