Castle Windsor:单元测试组件生命周期

时间:2013-05-22 14:54:59

标签: unit-testing castle-windsor

我想编写一个非回归测试来验证瞬态组件是否已被很好地释放。有些是通过直接注入ctor创建的,另一些是通过类型化工厂创建的。 我以为我可以这样做:

// Given
var rootComponent = container.Resolve<IRootComponent>();
var c1 = rootComponent.C1;
var c2 = c1.C2;
etc.

Assert.True(Container.Kernel.ReleasePolicy.HasTrack(c1));
Assert.True(Container.Kernel.ReleasePolicy.HasTrack(c2));

// When
c1.Close();

// Then
Assert.False(Container.Kernel.ReleasePolicy.HasTrack(c1));
Assert.False(Container.Kernel.ReleasePolicy.HasTrack(c2));

HasTrack()始终返回 false ,但如果我在调试模式下查看容器,我可以很好地跟踪我的组件。这是为什么?你对这样的测试有什么建议吗?

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

未跟踪组件的原因是组件及其依赖项没有任何退役要求。在这种情况下,windsor没有理由跟踪它们。

一般情况下使用windsor时,您应该只在容器上解析一次以获得顶级组件。所有其他组件均由工厂注入或创建。无需担心注入组件的实时时间。容器会为你处理它。

对于您使用工厂创建的瞬态组件,您应该意识到它们永远不会比自己的工厂更长时间(被跟踪)。因此,如果您不介意您的组件长期存在,那么就不需要释放它们(在工厂中使用destroy方法)。

对于我想要确保释放它们的组件,我通常会创建单元测试,我将其固定在工厂中。这样就可以很容易地测试是否会调用destroy。

我认为,您采用的方法不仅仅是测试代码,还包括容器。 IMHO windsor已经过很好的测试,测试应该关注你自己的代码。

祝你好运, Marwijn。

答案 1 :(得分:0)

两年太晚了,但这是一个考验。

public class DependsOnSomethingDisposable
{
    private readonly SomethingDisposable _disposable;

    public Boolean SomethingDisposableIsDisposed { get { return _disposable.Disposed; } }
    public DependsOnSomethingDisposable(SomethingDisposable disposable)
    {
        _disposable = disposable;
    }
}

public class SomethingDisposable : IDisposable
{
    public Boolean Disposed { get; private set; }
    public void Dispose()
    {
        Disposed = true;
    }
}

[TestClass]
public class WindsorLifestyleTests
{
    private IWindsorContainer _container;

    [TestInitialize]
    public void Setup()
    {
        _container = new WindsorContainer();
    }

    [TestCleanup]
    public void Cleanup()
    {
        _container.Dispose();
    }

    [TestMethod]
    public void TransientDependencyIsDisposed()
    {
        _container.Register(
            Component.For<DependsOnSomethingDisposable>().LifestyleTransient(),
            Component.For<SomethingDisposable>().LifestyleTransient()
            );
        var resolved = _container.Resolve<DependsOnSomethingDisposable>();
        _container.Release(resolved);
        Assert.IsTrue(resolved.SomethingDisposableIsDisposed);
    }

    [TestMethod]
    public void NonTransientDependencyIsNotDisposed()
    {
        _container.Register(
            Component.For<DependsOnSomethingDisposable>().LifestyleTransient(),
            Component.For<SomethingDisposable>().LifestyleSingleton()
            );
        var resolved = _container.Resolve<DependsOnSomethingDisposable>();
        _container.Release(resolved);
        Assert.IsFalse(resolved.SomethingDisposableIsDisposed);
    }
}