Tuesday, December 18, 2007

TypeMock, IDisposable objects, and the NullReferenceException

TypeMock gives you the ability to mock concrete classes in .NET which is a very powerful feature. In my particular case, I am mocking out some classes with Microsoft's Message Queuing package. I've noticed a quirk when working with a mock object of a class that implements IDisposable, and I am posting this work-around with the hope that it will help someone else.

If you mock an instance of a class that implements IDisposable, and assign it with the using construct, you will get a System.NullReferenceException in NUnit when running more than one test fixture at a time or upon closing NUnit if only running that one test fixture.

I think this describes what is happening: GC is fired, which appears to happen when NUnit exits or moves on to the next test fixture. The call to Dispose() has already been called by the using block, but does not suppress the finalizer since the call is mocked. Now, there is still a reference in the test to the object, so Finalize() will be called when GC is invoked and there is no way to mock this call at this point. The actual Close() method is called and since my object isn't fully constructed due to it being mocked, it is attempting in this case to do something with an uninitialized item.

As a work-around, call GC.SuppressFinalizer(obj) on the instance (not the mock object) after calling MockManager.Verify().

Update: Well, apparantly I am not the only person to run into this problem. The fine folks at TypeMock are planning a fix, although as of version 4.1 it isn't fixed yet. See this community posting for more info: http://www.typemock.com/community/viewtopic.php?p=2129&sid=31602cb52c52e180b20fc41d3b75f93a

No comments: