Should Dispose methods be unit tested?

Viewed 19662

I am using C#. Is it advised to unit test dispose methods? If so why, and how should one test these methods?

5 Answers

As a practical tip (because yes, you should test Dispose()) my experience has been that there are two ways to do so without too much hassle.

IDisposer

The first follows Igor's accepted answer - inject something like an IDisposer, so that you can call

public void Dispose()
{
    _disposer.Release(_disposable);
}

where

public interface IDisposer
{
    void Release(IDisposable disposable);
}

Then all you need to do is mock the IDisposer and assert that it's called once and you're golden.

Factory

The second, and my personal favourite, is to have a factory that creates the thing you need to test disposal of. This only works when the factory produces a mockable type (interface, abstract class), but hey, that's almost always the case, especially for something that's to be disposed. For testing purposes, mock the factory but have it produce a mock implementation of the thing you want to test disposal of. Then you can assert calls to Dispose directly on your mock. Something along the lines of

public interface IFooFactory
{
    IFoo Create(); // where IFoo : IDisposable
}

public class MockFoo : IFoo
{
    // ugly, use something like Moq instead of this class
    public int DisposalCount { get; privat set; }

    public void Dispose()
    {
        DisposalCount++;
    }
}

public class MockFooFactory
{
    public MockFoo LatestFoo { get; private set; }

    public IFoo Create()
    { 
        LatestFoo = new MockFoo();
        return LatestFoo;
    }
}

Now you can always ask the factory (which will be available in your test) to give you the latest MockFoo, then you dispose of the outer thing and check that DisposalCount == 1 (although you should use a test framwork instead, e.g. Moq).

Related