Unity容器在测试中使用时会丢失注册

时间:2012-01-11 12:36:44

标签: c# inversion-of-control unity-container mstest containers

我正在与一个在随机失败测试中遇到问题的团队合作。失败的测试似乎只在buildserver(TFS)上失败了。但是当我调查这个问题时,我能够让它们在我的本地机器上失败。

似乎我已经解决了这个问题,但我需要确认我的失败测试理论。

使用此TestInitialize方法失败的测试之一:

    [TestInitialize]
    public void TestInit()
    {
        Mock<ILog> loqMock = new Mock<ILog>();
        Depend.RegisterInstance(loqMock.Object);
    }

Depend类是Unity容器周围的静态包装器。它有一个对其中的Unity容器的本地引用。这个灯具中的一些测试看似随机失败。

我的理论是logMock变量被解除引用,因为在Initialize方法返回后没有引用或Depend类。

我通过将代码更改为“修复”了问题:

    private Mock<ILog> loqMock;

    [TestInitialize]
    public void TestInit()
    {
        loqMock = new Mock<ILog>();
        Depend.RegisterInstance(loqMock.Object);
    }

现在只要testfixture存在,就会引用logMock变量。我无法让它失败,就像我可以使用其他设置一样。

PS:我知道这个IOC容器的使用是一个非常糟糕的主意并且它应该被更改,但是我正在咨询的项目没有资源来进行更改,而且我没有什么可以做的。做到这一点。

1 个答案:

答案 0 :(得分:1)

Jand187, 你是100%正确的垃圾收集器正在收集loqMock对象。您只注册了由Mock创建的对象,该对象不包含对Mock对象本身的引用。

您可以验证这一点的一种方法是使用偶尔失败的设置,并在执行失败的行之前执行GC.Collect()。在调用GC之后,它每次都会失败。

如果您希望在单元测试的TestInit()方法中定义和初始化的对象在其持续时间内存活,则必须确保至少有一个对它的引用保留在“某个”对象中,将具有等于或长于测试持续时间的生命周期 - 在这种情况下,您的“修复”(引用引号)绝对正确。

如果您对原因和方式感兴趣,请点击此处链接到MS的一篇非常有用的文章,其中涵盖了垃圾收集:http://msdn.microsoft.com/en-us/library/ee787088.aspx

祝你好运!

亚当