I chased my tail on this one for probably about an hour. I have a helper method to set up some fakes. I was have a test fail that shouldn't of been and would only fail when ran in a particular order. It was obvious once I figured it out (a previous test didn't have the Isolated attribute), but finding it was a pain.
I'd propose a feature (since you're using Aspects and reflection heavily everywhere anyway), that if you make a call to something in Isolate class, that the calling method (or somewhere in the calling stack methods), must have the attribute of 'Isolated' applied.
Here's a demo of what I did to myself (very simplified, the real world this was buried) that got me in trouble:
Class under test:
public class SomeClassWithOneReturnMethod
{
public string WillReturnAString(string notUsed)
{
return "TEST";
}
}
Tests - individually they both pass:
[TestMethod()]
public void Test1()
{
//Arrange
SomeClassWithOneReturnMethod fake = Isolate.Fake.Instance<SomeClassWithOneReturnMethod>();
Isolate.WhenCalled(() => fake.WillReturnAString(null)).WillReturn("ABC");
Isolate.Swap.NextInstance<SomeClassWithOneReturnMethod>().With(fake);
//Because in real world we may go down a code path where another instance of fake might
//be created (depending on logic) and we want to make sure it returns ABC also
Isolate.Swap.NextInstance<SomeClassWithOneReturnMethod>().With(fake);
//Act
SomeClassWithOneReturnMethod target = new SomeClassWithOneReturnMethod();
string test = target.WillReturnAString(null);
//Assert
Assert.AreEqual<string>("ABC", test);
}
[Isolated(), TestMethod()]
public void Test2()
{
//Arrange
SomeClassWithOneReturnMethod fake = Isolate.Fake.Instance<SomeClassWithOneReturnMethod>();
Isolate.WhenCalled(() => fake.WillReturnAString(null)).WillReturn(null);
Isolate.Swap.NextInstance<SomeClassWithOneReturnMethod>().With(fake);
//Because in real world we may go down a code path where another instance of fake might
//be created (depending on logic) and we want to make sure it returns ABC also
Isolate.Swap.NextInstance<SomeClassWithOneReturnMethod>().With(fake);
//Act
SomeClassWithOneReturnMethod target = new SomeClassWithOneReturnMethod();
string test = target.WillReturnAString(null);
//Assert
Assert.AreEqual<string>(null, test);
}
But if you set up an ordered test where the first test is Test1 and the second test is Test2, the second test will fail because 'ABC' will be returned instead of null (because the clean up code for Test1 never ran meaning the swap next instance for the 2nd call was still valid).