单元测试中的模拟日志单例

时间:2018-05-22 13:52:00

标签: c# unit-testing singleton

我有一个记录器类,其目的是从我的解决方案中的任何类调用,谁决定记录某些东西。 我添加了一个界面,这就是我应用单例模式的原因,并没有使用静态类。

我的LogManager实现(单例): https://pastebin.com/NHKmbj9c

我想编写简单的单元测试,它们应该使用局部变量,测试每个ILogger方法的功能,但是一旦我的第一个单元通过,Singleton将在上下文中保持初始化,进行后续的单元测试失败(当他们试图初始化单身......)。

单元测试:

[TestClass]
public class LogManagerTests
{
    [TestMethod]
    public void Error_ExpectedErrorLevel_ShouldBe_Error()
    {
        // Arrange
        var actualLevel = ErrorLevel.Warning;
        const ErrorLevel expectedLevel = ErrorLevel.Error;
        var iLogger = LogManager.GetInstance;
        iLogger.Initialize((level, msg) => { actualLevel = level; }, null);

        // Act
        iLogger.Error(new Exception(), string.Empty);

        // Assert
        Assert.AreEqual(expectedLevel, actualLevel);
    }

    [TestMethod]
    public void Debug_ExpectedErrorLevel_ShouldBe_Verbose()
    {
        // Arrange
        var actualLevel = ErrorLevel.Warning;
        const ErrorLevel expectedLevel = ErrorLevel.Verbose;
        var iLogger = LogManager.GetInstance;
        iLogger.Initialize(null, (level, msg, ex) => { actualLevel = level; });

        // Act
        iLogger.Debug(string.Empty);

        // Assert
        Assert.AreEqual(expectedLevel, actualLevel);
    }
}

另一种方法是将LogManager初始化为我的TestClass中的私有全局变量,但是如果Unit测试运行异步,这可能会产生竞争条件,因为多个方法将访问相同的输出变量,这可能会覆盖彼此。< / p>

UnitTest是否有可能以任何方式单身?

该设计不允许我重构LogManager,并从中删除单例模式。

1 个答案:

答案 0 :(得分:0)

单元测试单例是可能的,你只需要以不同的方式思考它。不要试图改变您的方法以适应测试。考虑创建仅用于测试的方法LogManager.Uninitialize()。 在此组测试中的每次测试后调用此方法,以确保您的单例设置恢复到可测试状态。

[TestCleanup()]
public void Cleanup()
{
     LogManager.Uninitialize();
}

它可能不是纯粹的,但我认为每隔一段时间写一次诊断方法就好了。这比在需要良好测试覆盖率的情况下测试覆盖率更差。