4

我对单元测试比较陌生,对模拟完全陌生。我有一个包装 DbProvider 工厂的数据库类,我想在不连接到数据库的情况下为其创建单元测试。

我将如何模拟 DbProvider 工厂,以便我可以将它传递给我的课程?我还需要模拟 DbConnection、DbCommand 等吗?我的代码的一个小示例如下:

public Database(DbProviderFactory dbProviderFactory) {
    Provider = dbProviderFactory;
}

public int UpdateRecords(string sql, CommandType type, params DbParameter[] parameters) {
    int numberOfRecordsUpdated;

    using (var connection = CreateConnection()) {

        // Add ConnectionString
        connection.ConnectionString = ConnectionString;

        // Create command to hold the update statment
        using (var command = CreateCommand()) {
            try {
                command.Connection = connection;
                command.CommandType = type;
                command.CommandText = sql;

                // Add Parameters
                foreach (var parameter in parameters) {
                    command.Parameters.Add(parameter);
                }

                // Open Connection
                connection.Open();

                // Execute SQL
                numberOfRecordsUpdated = command.ExecuteNonQuery();
            } finally {
                command.Parameters.Clear();
            }
        }
    }

    return numberOfRecordsUpdated;
}
4

3 回答 3

2

集成测试


如果您有兴趣(根据您的评论判断)测试从数据库中获取数据,您将执行integration test.

这些类型的测试的不同之处unit testing在于它们运行的​​频率较低 - 最佳实践要求您在提交源代码控制之前运行这些测试。

原因是它们速度较慢,您将访问一个真实的数据库(至少是一个测试数据库)。在每次运行时,您都需要擦除数据库或不提交更改——您似乎知道自己在做什么,所以我将把如何处理这件事留给您自己。

嘲笑


至于测试使用数据库的逻辑 - 这mockingdependency injection要走的路。

我使用Moq——它可能是最容易使用的模拟框架。它实际上不仅适用于模拟对象(尽管名称如此),您可以使用它生成存根和伪造品。

伪模拟是这样的(使用数据库示例):

  • 设置模拟
  • 告诉它要做什么(期望)——例如调用保存。
  • 使用您的 SUT(被测系统)
  • 验证模拟 - 在这种情况下,您的 SUT 中调用了 save 方法。

如需进一步帮助 - 查看 Google - 有一些很好的资源可用于单元测试和模拟。

于 2009-09-16T20:46:11.737 回答
1

我会亲自模拟包含更高级别数据访问功能(如 UpdateRecords 等)的类,并使用此模拟返回预定的数据集。

DbProvider 和相应的 DbCommand 等的使用是数据访问层的实现细节,与使用返回值的更高级别的功能并不真正相关。

于 2009-09-16T20:46:59.367 回答
0

数据访问类都是关于与 DB 集成的。例如,Roy Osherove 在单元测试时将此类视为异常。我也对如何测试这种类型的代码感兴趣。+1 提问。

IOW 我不确定是否建议模拟数据访问类。

在单元测试方面什么不能测试?

于 2009-09-16T12:54:41.173 回答