Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 模拟DbProviderFactory_C#_Unit Testing_Mocking_Dbproviderfactories - Fatal编程技术网

C# 模拟DbProviderFactory

C# 模拟DbProviderFactory,c#,unit-testing,mocking,dbproviderfactories,C#,Unit Testing,Mocking,Dbproviderfactories,我对单元测试比较陌生,对模拟也完全陌生。我有一个数据库类,它包装了DbProvider工厂,我希望在不连接数据库的情况下为其创建单元测试 如何模拟DbProvider工厂,以便传入它来测试我的类?我还需要模拟DbConnection、DbCommand等吗。?下面是我的代码的一个小示例: public Database(DbProviderFactory dbProviderFactory) { Provider = dbProviderFactory; } public int Up

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

数据访问类都是关于与数据库集成的。例如,Roy Osherove在单元测试时认为这类是一个例外。我也对如何测试这类代码感兴趣+问题1

我不确定模仿数据访问类是否可取

集成测试
如果您对测试从数据库获取数据感兴趣(根据您的评论判断),您将执行
集成测试

对于这些类型的测试,
单元测试
的区别在于它们运行的频率较低-最佳实践要求您在提交到源代码管理之前运行这些测试

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

嘲笑
至于测试使用数据库的逻辑-
mock
dependency injection
是一种方法

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

伪模拟是这样的(使用DB示例):

  • 建立模拟
  • 告诉它要做什么(期望)-例如,呼叫保存
  • 使用SUT(测试中的系统)
  • 验证模拟-在本例中,save方法是在SUT中调用的

要获得进一步的帮助,请查看Google-有一些很好的资源用于单元测试和模拟。

我个人会模拟包含更高级别数据访问功能(如更新记录等)的类,并使用此模拟返回预定的数据集


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

您使用或计划使用什么模拟框架?这仍然是悬而未决的问题。我听过很多关于犀牛嘲弄的故事,但也听过关于Moq的好消息。当我说我对嘲弄还不熟悉时,我的意思是幼稚。我同意这一点,但有时我会觉得我所做的大部分工作都是从数据库中获取数据,或者对其执行逻辑。这个问题更多的是测试使用这个类的函数,允许我返回一个预先确定的数据集,并测试生成的功能。如果您遵循SRP原则,那么您将拥有单独的类,例如DataGetter和DataProcessor。因此,DataProcessor是单元测试的理想候选者。然后,您将制作一个模拟或存根来代替DataGetter,并在DataProcessor上执行操作。不涉及任何数据库。您必须配置伪造DataGetter的mock/stub,以便它从DB中检索模拟真实数据的数据。为了测试DataGetter DB,必须参与其中。这不再是单元测试了,但我不知道还有其他的方法来测试数据访问类。你没有给他解释。他希望模拟数据库类,如DbConnection,以避免将测试转换为集成测试。模拟所有的DbTransactions、DbConnection、DbCommands等等都是大量的模拟。因此,我解释这个问题。