为什么启用 JetBrains dotCover 会导致 NUnit 测试失败?
Why does enabling JetBrains dotCover cause NUnit test to fail?
我编写了一些如下所示的代码,以对 C# 终结器方法的实现进行单元测试。
在 TeamCity 版本 2017.1.3 中,我使用 NUnit 运行ner 类型的构建步骤 运行 此测试使用 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# 终结器方法的实现进行单元测试。
在 TeamCity 版本 2017.1.3 中,我使用 NUnit 运行ner 类型的构建步骤 运行 此测试使用 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;