hi
supposing i have the following class:
public class LegacyClass
{
private IDisposable _disposable = new MemoryStream();
~LegacyClass()
{
_disposable.Dispose();
}
}
I want to fake it:
[TestMethod]
[Isolated]
public void TestMethod1()
{
LegacyClass fake = Isolate.Fake.Instance<LegacyClass>();
}
of course the above test passes, but what if i have another test methods?
like this:
[TestMethod]
public void TestMethod2()
{
while (true)
{
Thread.Sleep(2);
GC.Collect();
}
}
now if i run the both tests, supposing TestMethod1 runs before TestMethod2, the VSTestHost.exe will crash with the following Exception:
One of the background threads threw exception: System.NullReferenceException: Object reference not set to an instance of an object.
in DestructorTypeMock.LegacyClass.Finalize() in d:cs8DestructorTypeMockDestructorTypeMockLegacyClass.cs:line 14
Test host process exited unexpectedly.
however this is not happening if i removing the [Isolated] attribute.
You can see that this is happening from the LegacyClass destructor, the GC.Collect(); command is there only to rapidly reproduce the behavior.
the first thing i thinked about is to add the GC.SuppressFinalize(fake); call. this is helping with this specific case, but not with the following case:
public class Program
{
public static void Main(string[] args)
{
new LegacyClass();
}
}
[TestMethod]
[Isolated]
public void TestMethod1()
{
LegacyClass fake = Isolate.Fake.Instance<LegacyClass>();
GC.SuppressFinalize(fake);
Isolate.Swap.AllInstances<LegacyClass>().With(fake);
Program.Main(null);
}
the GC.SuppressFinalize will applies only to the fake that test created, not to the fake that the Main created, and the above crash and exception occures again.
i think that the Isolator api should have a "SuppressFakeFinalize" method, or at least by default prevent executing of destructors on fakes.