David Schmitt
David Schmitt

Reputation: 59346

How to unit test IDisposable?

I'm working on a piece of library code around IDisposable. The managed path (via using) is easily testable. I'm wondering about the finalizer though: Is calling System.GC.Collect() sufficient to force the finalizer to run?

Upvotes: 10

Views: 5062

Answers (4)

Rob McCready
Rob McCready

Reputation: 1919

I would take a look at Dispose, Finalization, and Resource Management its the best reference on the subject I know of. Using their pattern:

~ComplexCleanupBase()
{
    Dispose(false);
}

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected override void Dispose(bool disposing)
{
   if (!disposed)
   {
        if (disposing)
        {
            // dispose-only, i.e. non-finalizable logic
        }

        // new shared cleanup logic
        disposed = true;
    }

    base.Dispose(disposing);
}

You wind up with dead simple Finalizer/Dispose() methods and a testable Dispose(bool). No need to force Finalization or anything using the GC class.

Upvotes: 2

Ben Fulton
Ben Fulton

Reputation: 3998

I think I would lean towards making Finalize() call another method, and test that the other method does what you want. You wouldn't get 100% code coverage, but at least you'd know that the method releases the object's resources properly.

Upvotes: 0

RickL
RickL

Reputation: 2821

No, the GC.Collect() call is asynchronous, you would also need to call this:

System.GC.WaitForPendingFinalizers();

Upvotes: 8

brien
brien

Reputation: 4440

Could you mock out an IDisposable interface and expect a call to Dispose? That would at least let you see when the object is actually disposed.

Upvotes: 0

Related Questions