c#-3.0 - MSTest 与 Moq - DAL 设置

标签 c#-3.0 moq enterprise-library mstest data-access-layer

我是 Moq 新手,刚刚开始一个已经在开发的项目。我负责设置单元测试。 DatabaseFactory 有一个使用 EnterpriseLibrary 的自定义类,如下所示:

public Database CreateCommonDatabase()
{
  return CreateDatabaseInstance(string.Empty);
}

private static Database CreateDatabaseInstance(string foo)
{
  var database = clientCode == string.Empty
      ? DatabaseFactory.CreateDatabase("COMMON")
      : new OracleDatabase(new ClientConnections().GetConnectionString(foo)));
  return database;
}

现在,这是使用它的地方(ResultData 是 DataSet 类型的另一个类):

public ResultData GetNotifications(string foo, string foo2, Database database)
{
    var errMsg = string.Empty;
    var retval = 0;
    var ds = new DataSet();

    var sqlClause =
    @"[Some SELECT statement here that uses foo]";

    DbCommand cm = database.GetSqlStringCommand(sqlClause);
    cm.CommandType = CommandType.Text;

    // Add Parameters
    if (userSeq != string.Empty)
    {
      database.AddInParameter(cm, ":foo2", DbType.String, foo2);
    }

    try
    {
      ds = database.ExecuteDataSet(cm);
    }
      catch (Exception ex)
    {
      retval = -99;
      errMsg = ex.Message;
    }

    return new ResultData(ds, retval, errMsg);
}

现在,最初,数据库并未作为参数传入,但该方法使用 CreateCommonDatabase 方法创建 DatabaseFactory 的新实例,并从那里使用它。然而,这使得该类无法测试,因为我无法阻止它实际访问数据库。因此,我采用了依赖注入(inject),并将数据库传入。

现在,我陷入了困境,因为无法模拟数据库来测试 GetNotifications。我想知道我是否把事情过于复杂化了,或者我是否遗漏了一些东西。我这样做的方式正确吗,还是应该重新考虑如何设置?

编辑以添加更多信息*****

我真的不想测试数据库。我希望 Data.Notifications 类(上面)返回 ResultData 的实例,但这就是我真正想要测试的全部。如果我上升到业务层,我会得到以下内容:

public DataSet GetNotifications(string foo, string foo1, out int returnValue, out string errorMessage, Database database)
{
    ResultData rd = new data.Notifications().GetNotifications(foo, foo1, database);

    returnValue = rd.ResultValue;
    errorMessage = rd.ErrorMessage;

    return rd.DataReturned;
}

所以,最初,数据库没有传入,而是 Data.Notifications 类创建了它 - 但话又说回来,如果我这样保留它,我就忍不住要点击数据库来测试这个业务层对象。我修改了所有代码以传递数据库(它创建了网络的基本页面),但现在我不确定下一步要做什么。我以为我只需要一个单元测试就可以解决这个问题,但显然,要么我错了,要么我在正确的道路上遇到了心理障碍。

最佳答案

如果其中的方法是虚拟的,您应该能够创建一个模拟数据库对象。如果不是,那么你就遇到了一些问题。

我不知道“数据库”是什么类型,但你有几个选择。

  1. 如果您拥有数据库的源代码,我建议提取接口(interface) IDatabase,而不是处理数据库类类型。这将消除一些复杂性并为您提供非常可测试的东西。

  2. 如果您无权访问 Database 类,您始终可以通过另一层抽象来解决此问题。在这种情况下,许多人使用包装数据访问层的存储库模式。一般来说,在这种情况下,大多数人将测试 Respository 类留给集成测试(没有任何隔离的测试),而不是单元测试。

以下是使用选项 #1 设置测试的方法:

[TestMethod]
public void GetNotifications_PassedNullFoo_ReturnsData()
{
     //Arrange
     Mock<IDatabase> mockDB = new Mock<IDatabase>();
     mockDB.Setup(db => db.ExecuteDataSet()).Returns(new DataSet() ... );

     //Act
     FooClass target = new fooClass();
     var result = target.GetNotifications(null, "Foo2", mockDB.Object);

     //Assert
     Assert.IsTrue(result.DataSet.Rows.Count > 0);
}

我的数据集代码有点生疏,但希望这能为您提供总体思路。

关于c#-3.0 - MSTest 与 Moq - DAL 设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2180363/

相关文章:

c++ - 在 C# 中将数组数组传递给 DLL 的安全方法是什么?

linq - 等同于 JOIN 的点符号

c# - 在运行时停止/启动 WCF MEX 服务

c# - Enterprise Library 5.0如何安装?

c# - 使用字符数组列表执行多个字符串连接是否更快?

.net - 单元测试 MongoDB.Driver dotnet core

Moq 和 Moq Contrib 版本

c# - 如何使 FakeItEasy 伪造对象的方法在第一次调用时抛出并在第二次调用时返回?

c# - 企业库验证 block

.net - C# .NET v3.5 应用程序的日志记录/错误处理框架的最佳方法? (企业库/log4net/?)