【问题标题】:Mocking DbProviderFactory模拟 DbProviderFactory
【发布时间】:2010-11-28 19:10:53
【问题描述】:

我对单元测试比较陌生,对模拟完全陌生。我有一个包装 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;
}

【问题讨论】:

  • 你使用或计划使用什么模拟框架?
  • 那还没有定论。我听说过很多关于 Rhino Mocks 的事,但也听说过关于 Moq 的好消息。当我说我不熟悉嘲弄时,我的意思是幼稚。

标签: c# unit-testing mocking dbproviderfactories


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    集成测试


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

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

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

    嘲讽


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

    我使用Moq - 它可能是最容易使用的模拟框架。它实际上不仅适用于模拟对象(尽管有名称),您可以使用它生成 stubs and fakes

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

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

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

    【讨论】:

    • 你误解了他。他想mock 数据库类,例如 DbConnection,以便 将测试变成集成测试。模拟所有的 DbTransactions、DbConnection、DbCommands 和所有这些都是很多的模拟。因此,我解释它的问题。
    【解决方案3】:

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

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

    What not to test when it comes to Unit Testing?

    【讨论】:

    • 我同意这一点,但有时我觉得我所做的大部分工作都是处理从数据库中获取数据或执行逻辑。这个问题更多的是测试使用这个类的函数,允许我返回一个预定的数据集,并测试结果功能。
    • 如果您遵循 SRP 原则,您将拥有单独的类,例如数据获取器和数据处理器。 DataProcessor 是单元测试的理想候选者。然后,您将制作一个模拟或存根来代替 DataGetter 并在 DataProcessor 上执行操作。不涉及数据库。您必须配置伪造 DataGetter 的模拟/存根,以便它返回模拟来自 DB 的真实数据的数据。为了测试 DataGetter DB 必须参与。它不再是单元测试,但我不知道测试数据访问类的其他方法。
    猜你喜欢
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 2012-04-08
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    相关资源
    最近更新 更多