在另一个 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();
}
_logContext
是 LogContext
类型的全局变量,通过构造函数注入。
你可以模拟它并通过构造函数传递模拟。
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 您在配置中提供的数据。
我正在使用 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();
}
_logContext
是 LogContext
类型的全局变量,通过构造函数注入。
你可以模拟它并通过构造函数传递模拟。
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 您在配置中提供的数据。