C# 单元测试 void 静态方法
C# UnitTest void static method
我正在尝试对应用程序中的记录器进行单元测试。
例如,我需要测试方法 Logger.info("some message")
,但此方法是静态的并且 return 无效。
在 Google 上搜索,我知道我必须使用 Moq,但无法在 UnitTest class 上实现它。
Logger 构造函数没有参数,在 x.Debug
中我有一个错误提示我无法访问
来自实例参考。
有没有办法在不编辑生产代码的情况下实现单元测试?
[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;
}
}
Program.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);
}
您不能模拟静态 class,也不应模拟正在测试的 class/system。
向记录器添加模拟附加程序:
// 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();
请注意,此静态 class 可能会在测试之间保留数据,从而导致意外结果,请咨询您的测试框架以进行配置。
除此之外,您通常不想推出自己的日志记录基础设施,有很多事情您可能会做错,为什么要重新发明轮子?大量 ILogger(<T>)
实现。
我正在尝试对应用程序中的记录器进行单元测试。
例如,我需要测试方法 Logger.info("some message")
,但此方法是静态的并且 return 无效。
在 Google 上搜索,我知道我必须使用 Moq,但无法在 UnitTest class 上实现它。
Logger 构造函数没有参数,在 x.Debug
中我有一个错误提示我无法访问
来自实例参考。
有没有办法在不编辑生产代码的情况下实现单元测试?
[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;
}
}
Program.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);
}
您不能模拟静态 class,也不应模拟正在测试的 class/system。
向记录器添加模拟附加程序:
// 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();
请注意,此静态 class 可能会在测试之间保留数据,从而导致意外结果,请咨询您的测试框架以进行配置。
除此之外,您通常不想推出自己的日志记录基础设施,有很多事情您可能会做错,为什么要重新发明轮子?大量 ILogger(<T>)
实现。