在另一个 class 中使用 JustMock 模拟一个 Entity Framework class

Mock an Entity Framework class with JustMock inside another class

我正在使用 JustMock 和 Entity Framework 尝试为服务编写单元测试。在服务中,我有这个方法:

List<Log> GetLogType(string type)
{
    using (var db = new LogContext())
    {
        return db.Logs.Where(x => x.Type == type).ToList();
    }
}

我有一个测试:

[TestMethod]
public void GetLogTypeTest()
{
    IList<Log> logs = new List<Log>
    {
        new Log() {
            Id = 1,
            Type = "Debug",
            Message = "Test Message"
        }
    };

    var logContext = Mock.Create<LogContext>(Constructor.Mocked).PrepareMock();
    logContext.Logs.Bind(logs);

    var service = new LogService();

    var debugs = service.GetLogType("Debug");

    Assert.AreEqual(1, debugs.Count());
}

如何让服务使用我的模拟上下文?现在它正在尝试连接到数据库,因此出错。

原因

这不是因为 JustMock 而发生的。发生这种情况是因为您在方法中创建了 LogContext 的新实例。您的方法不可单元测试,因为它总是会创建新的服务实例并与真实数据库建立连接。有几个适用于 C# 的依赖注入框架,如果您有兴趣,请查看 Unity

解决这个问题

您必须使用依赖注入并在 class 中注入您的服务。在这种情况下,您可以避免连接到数据库。您的方法将是这样的:

List<Log> GetLogType(string type)
{
    return _logContext.Logs.Where(x => x.Type == type).ToList();    
}

_logContextLogContext 类型的全局变量,通过构造函数注入。

你可以模拟它并通过构造函数传递模拟。

class 的示例可以是:

public class LogService
{
    private readonly LogContext _logContext;

    public LogService(LogContext logContext)
    {
       _logContext = logContext;
    }

    List<Log> GetLogType(string type)
    {
        return _logContext.Logs.Where(x => x.Type == type).ToList();    
    }
}

现在您可以像下面这样创建测试用例:

[TestMethod]
public void GetLogTypeTest()
{
    IList<Log> logs = new List<Log>
    {
        new Log() {
            Id = 1,
            Type = "Debug",
            Message = "Test Message"
        }
    };

    var logContext = Mock.Create<LogContext>(Constructor.Mocked).PrepareMock();
    logContext.Logs.Bind(logs);

    var service = new LogService(logContext);

    var debugs = service.GetLogType("Debug");

    Assert.AreEqual(1, debugs.Count());
}

请注意我做了什么。我像你一样创建了 service 实例,但我通过构造函数注入了真实服务的模拟实例。模拟实例永远不会连接到数据库,它将 return 您在配置中提供的数据。