【问题标题】:C# UnitTest void static methodC#单元测试void静态方法
【发布时间】:2022-01-02 08:54:12
【问题描述】:

我正在尝试对应用程序中的记录器进行单元测试。 例如我需要测试方法Logger.info("some message"),但是这个方法是静态的并且返回void。 在 Google 上搜索我知道我必须使用 Moq,但无法在 UnitTest 类上实现它。 Logger 构造函数没有参数,在x.Debug 我有一个错误,说我无法访问 从实例参考。 有没有办法在不编辑生产代码的情况下实现 UnitTest?

[TestClass()]
public class LoggerTests
{
    [TestMethod()]
    public void DebugTest()
    { 
        var mock = new Mock<Logger>();
        mock.Setup(x => x.Debug(It.IsAny<string>());
        new Logger(mock.Object).AddLog("testing");
        mock.VerifyAll;
    }
}

程序.cs

private static void ConfigureLogger()
{
    Logger.AddLog(new NLogAppender());
    Logger.Level = TraceLevel.Verbose;
    Logger.Info("Configured Logger");
}

Logger.cs

public class Logger
{
    public static readonly List<IAppender> loggings = new List<IAppender>();

    public static void AddLog(IAppender appender)
    {
        loggings.Add(appender);
    }

    public static TraceLevel Level { get; set; }

    static Logger()
    {
        Level = TraceLevel.Verbose;
    }

    public static void Info(string message)
    {
        LogMessage(message);
    }
}

NlogAppender.cs

public class NLogAppender : IAppender
{
    public NLog.Logger logger;

    public NLogAppender()
    {
        logger = LogManager.GetLogger(nameof(NLogAppender));
    }

    public void AddLog(string str)
    {
    }
}

IAppender.cs

public interface IAppender
{
    void AddLog(string str);
}

【问题讨论】:

  • 让你的 Logger 不是静态的并且可以通过一个接口通过依赖注入来访问,这将不会那么痛苦。
  • 实际上我无权编辑代码。我只在 UnitTest 上工作。我可以在开发人员处让 DI 访问。我想知道是否有办法避免更改代码。如果太复杂,我会与团队讨论并发布更新。

标签: c# unit-testing static void


【解决方案1】:

您不能模拟静态类,也不应该模拟被测类/系统。

向记录器添加一个模拟追加器:

// Arrange
var logString = "test-info"

var appenderMock = new Mock<IAppender>();

appenderMock.Setup(a => a.AddLog(logString));

Logger.AddLog(appenderMock.Object);

// Act
Logger.Info(logString);

// Assert
// TODO: exactly once
appenderMock.VerifyAll();

请注意,此静态类可能会在测试之间保留数据,从而导致意外结果,请咨询您的测试框架以进行配置。

除此之外,您通常不想推出自己的日志记录基础架构,您可能会做错很多事情,为什么要重新发明轮子?大量的ILogger(&lt;T&gt;) 实现。

【讨论】:

  • Perfect 现在似乎可以工作,即使测试失败。明天我试着理解为什么。反正我最近才加入开发组,还是要明白所有开发选择的原因。同时,谢谢!
  • 问题已修复,这只是将多个参数传递给函数的干扰。 (我在此处显示的代码中删除了一些内容)
  • 乐于助人!
猜你喜欢
  • 1970-01-01
  • 2018-08-23
  • 2019-05-11
  • 2017-05-11
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
相关资源
最近更新 更多