我对单元测试很陌生。虽然我可以进行简单的单元测试,但我发现很难理解依赖注入部分。我有 2 个场景无法创建测试
- 数据库连接
- 日志文件处理
虽然我搜索了互联网,但我找不到任何简单的示例来遵循和实现这些模拟。
最小起订量是否支持具体类,或者我是否需要将所有实现更改为虚拟以进行单元测试。非常感谢任何示例代码或示例代码的链接
我对单元测试很陌生。虽然我可以进行简单的单元测试,但我发现很难理解依赖注入部分。我有 2 个场景无法创建测试
虽然我搜索了互联网,但我找不到任何简单的示例来遵循和实现这些模拟。
最小起订量是否支持具体类,或者我是否需要将所有实现更改为虚拟以进行单元测试。非常感谢任何示例代码或示例代码的链接
首先,Moq 不支持模拟具体类。只能模拟抽象类和接口。然而,这并不像听起来那么难。让我们以您的日志文件处理为例。
假设您从以下具体的日志记录类开始:
public class Log
{
public void WriteToLog(string message)
{
...
}
}
我们还有另一个类使用这个Log
类来进行日志记录:
public class LogGenerator
{
public void Foo()
{
...
var log = new Log();
log.WriteToLog("my log message");
}
}
对方法进行单元测试的问题Foo
是您无法控制Log
类的创建。第一步是应用控制反转,调用者可以决定使用哪些实例:
public class LogGenerator
{
private readonly Log log;
public LogGenerator(Log log)
{
this.log = log;
}
public void Foo()
{
...
this.log.WriteToLog("my log message");
}
}
现在我们离成功进行单元测试又近了一步,因为我们的单元测试可以选择使用哪个Log
实例进行日志记录。现在的最后一步是使Log
类可模拟,我们可以通过添加一个由该接口ILog
实现Log
并LogGenerator
依赖于该接口的接口来实现:
public interface ILog
{
void WriteToLog(string message);
}
public class Log : ILog
{
public void WriteToLog(string message)
{
...
}
}
public class LogGenerator
{
private readonly ILog log;
public LogGenerator(ILog log)
{
this.log = log;
}
public void Foo()
{
...
this.log.WriteToLog("my log message");
}
}
现在我们可以在我们的单元测试中使用 Moq 来创建一个对象实现的模拟ILog
:
public void FooLogsCorrectly()
{
// Arrange
var logMock = new Mock<ILog>();
var logGenerator = new LogGenerator(logMock.Object);
// Act
logGenerator.Foo();
// Assert
logMock.Verify(m => m.WriteToLog("my log message"));
}