I want to write unit tests for a class that implements IDisposable. The class has numerous private fields that also implement IDisposable. In my test, I want to verify that when I call Dispose(), it correctly calls Dispose() on all of its IDisposable fields. Essentially, I want my unit test to look like this:
var o = new ObjectUnderTest();
o.Dispose();
Assert.IsFalse(ObjectHasUndisposedDisposables(o));
I was thinking of using reflection to achieve this. It seems like this would be a fairly common requirement, but I can't find any examples of it.
Anyone tried this?
EDIT -- I do NOT want to have to inject the Disposables into the class under test.
The only way to verify the behavior you are looking for without any refactoring in your code is to use code weaving tools Eg; Typemock Isolator, MsFakes and etc...
The following snippet show the way to verify the behavior using MsFakes:
[TestMethod]
public void TestMethod1()
{
var wasCalled = false;
using (ShimsContext.Create())
{
ForMsFakes.Fakes.ShimDependency.AllInstances.Dispose = dependency =>
{
wasCalled = true;
};
var o = new ObjectUnderTest();
o.Dispose();
}
Assert.IsTrue(wasCalled);
}
public class Dependency : IDisposable
{
public void Dispose() {}
}
public class ObjectUnderTest: IDisposable
{
private readonly Dependency _d = new Dependency();
public void Dispose()
{
_d.Dispose();
}
}
There is no generic way to handle this. the IDisposeable interface does not require you to track if dispose has been called or not.
The only way I could think of that you could handle this is if all of those disposable classes where injected using dependency injection. If you did that you could mock the injected classes and track if dispose was called.
[TestMethod]
public void TestAllDisposeablesAreDisposed()
{
var fooMock = new Mock<IFoo>();
fooMock.Setup(x=>x.Dispose())
.Verifiable("Dispose never called on Foo");
var barMock = new Mock<IBar>();
barMock.Setup(x => x.Dispose())
.Verifiable("Dispose never called on Bar");
using (var myClass = new MyClass(fooMock.Object, barMock.Object))
{
}
fooMock.Verify();
barMock.Verify();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With