I’m working with a team that have had problems with random failing tests. The failing tests seemingly only failed on the buildserver (TFS). But as I investigated the problem I was able to have them fail on my local machine as well.
It seems that I have fixed the problem, but I need confirmation of my theory about the failing tests.
One of the tests that failed had this TestInitialize method:
[TestInitialize]
public void TestInit()
{
Mock<ILog> loqMock = new Mock<ILog>();
Depend.RegisterInstance(loqMock.Object);
}
The Depend class is a static wrapper around the Unity container. It has a local reference to the Unity container inside it. Some tests in this fixture fails seemingly at random.
My theory is that the logMock variable is dereferenced, since there is no reference to either that or the Depend class after the Initialize method returns.
I “fixed” the problem by changing the code to this:
private Mock<ILog> loqMock;
[TestInitialize]
public void TestInit()
{
loqMock = new Mock<ILog>();
Depend.RegisterInstance(loqMock.Object);
}
Now the logMock variable is referenced as long as the testfixture lives. I cannot get it to fail, as I could with the other setup.
PS: I know that this use of an IOC container is a really bad idea and that it should be changed, but the project I’m consulting, doesn’t have the resources to make the change, and there’s nothing I can do about it.
Jand187,
You’re 100% right that the loqMock object is being gathered up by the garbage collector. You’re only registering the object which is being created by your Mock, which doesn’t contain a reference back to the Mock object itself.
One way you can verify this is to use the setup where it fails occasionally, and before executing the line where it would fail do a GC.Collect(). After invoking the GC, it should fail every time.
If you want the object which defined and initialized within the TestInit() method of your unit test to live for the duration of it, you’ll have to ensure at least one reference to it is kept within “some” object which will have a lifecycle equal to or longer than your the duration of the test – in this case, your “fix” (quoting quotes) is absolutely correct.
If you’re interested in the why and how, here’s a link to a very useful writeup by MS covering Garbage Collection relatively deeply: http://msdn.microsoft.com/en-us/library/ee787088.aspx
Good luck!
Adam