需要Moq简单示例 - 数据库连接和文件处理

kar*_*nai 5 c# nunit unit-testing moq

我对单元测试很陌生.虽然我可以进行简单的单元测试,但我发现很难理解依赖注入部分.我有2个场景,我无法创建测试

  1. 数据库连接
  2. 日志文件处理

虽然我搜索了互联网,但我找不到任何简单的例子来实现这些嘲弄.

Moq是否支持具体类,或者我是否需要将所有实现更改为虚拟单元测试.非常感谢示例代码的任何示例代码或链接

Eri*_*oom 10

首先,起订量并没有支持嘲弄具体类.只能抽象抽象类和接口.然而,这并不像听起来那么难.我们以您的日志文件处理为例.

假设您从以下具体的日志记录类开始:

public class Log
{
    public void WriteToLog(string message)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我们有另一个使用此类Log进行日志记录的类:

public class LogGenerator
{
    public void Foo()
    {
        ...

        var log = new Log();
        log.WriteToLog("my log message");
    }
}
Run Code Online (Sandbox Code Playgroud)

单元测试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");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们距离成功进行单元测试又近了一步,因为我们的单元测试可以选择使用哪个Log实例进行日志记录.现在的最后一步是使Log类可模拟,我们可以通过添加由该接口ILog实现LogLogGenerator依赖于该接口的接口来实现:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以在单元测试中使用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"));
}
Run Code Online (Sandbox Code Playgroud)