如何使用反射对Dispose()进行单元测试?

use*_*784 3 c# reflection unit-testing assert dispose

我想为实现IDisposable的类编写单元测试.该类有许多私有字段,也实现IDisposable.在我的测试中,我想验证当我调用时Dispose(),它正确调用Dispose()其所有IDisposable字段.基本上,我希望我的单元测试看起来像这样:

var o = new ObjectUnderTest();
o.Dispose();
Assert.IsFalse(ObjectHasUndisposedDisposables(o));
Run Code Online (Sandbox Code Playgroud)

我正在考虑使用反射来实现这一目标.看起来这是一个相当普遍的要求,但我找不到它的任何例子.

有人试过吗?

编辑 - 我不想将Disposables注入被测试的类中.

Old*_*Fox 6

验证您正在寻找的行为而不在代码中进行任何重构的唯一方法是使用代码编织工具Eg; Typemock隔离器,MsFakes等......

以下代码段显示了使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)


Sco*_*ain 5

没有通用的方法来处理这个问题.该IDisposeable接口不需要你跟踪如果处置被称为与否.

我能想到你能解决的唯一方法就是使用依赖注入注入所有这些一次性类.如果你这样做,你可以模拟注入的类并跟踪是否调用dispose.

    [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();
    }
Run Code Online (Sandbox Code Playgroud)