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

本文关键字:注册 测试 Unity | 更新日期: 2023-09-27 18:19:56

我所在的团队在随机失败测试方面遇到了问题。失败的测试似乎只在构建服务器(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容器是一个非常糟糕的主意,应该改变它,但我正在咨询的项目没有资源进行改变,我对此无能为力。

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

1987年1月,垃圾收集器正在收集loqMock对象,这一点你说得100%正确。您只注册了Mock创建的对象,该对象不包含对Mock对象本身的引用。

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

如果你想让在单元测试的TestInit()方法中定义和初始化的对象在它的持续时间内生存,你必须确保至少有一个对它的引用保留在"某个"对象中,该对象的生命周期等于或长于你的测试持续时间-在这种情况下,你的"修复"(引用引号)是绝对正确的。

如果您对原因和方式感兴趣,这里有一个链接,链接到MS撰写的一篇非常有用的文章,该文章相对深入地介绍了垃圾回收:http://msdn.microsoft.com/en-us/library/ee787088.aspx

祝你好运

Adam