c# - 单元测试数据访问层的方法

标签 c# unit-testing testing persistence data-access-layer

我一直在尝试寻找一种有效的方法来对 C# 中的数据访问层进行单元测试。我是一名主要的 Java 开发人员,只使用 C# 大约 6 个月,过去我使用一个名为 DBUnit 的库来测试已知状态数据库。我还没有找到可以使用的类似事件库,最接近的似乎是 nDBUnit,但它现在已经有一段时间没有事件了。

在 C# 中似乎有很多关于如何以及为什么相互冲突的方法。理想情况下,我想在不需要连接到数据库的情况下使用模拟来测试数据访问层,然后在一组单独的测试中对存储过程进行单元测试。

在我正在处理的系统中,数据访问层是使用 ADO.net(不使用 Entity Framework )来调用 SQL Server 上的存储过程。

下面是我必须使用的示例代码;要走模拟路径,我必须能够模拟 SqlCommand(使用 IDbCommand)和/或模拟 SqlConnection。

所以我的问题是什么似乎是最好的方法(如果有这样的事情)?到目前为止,唯一的方法是制作传递给构造函数的 Proxy 对象,以便它可以返回模拟的 Sql* 对象进行测试。

我还没有机会查看所有可用的 C# 模拟库。

public class CustomerRepository : ICustomerRepository
{
   private string connectionString;

   public CustomerRepository (string connectionString)
   {
     this.connectionString = connectionString;
   }

   public int Create(Customer customer)
   {

     SqlParameter paramOutId = new SqlParameter("@out_id", SqlDbType.Int);
     paramOutId.Direction = ParameterDirection.Output;
     List<SqlParameter> sqlParams = new List<SqlParameter>()
     {
       paramOutId,
       new SqlParameter("@name", customer.Name)
     }

     SqlConnection connection = GetConnection();
     try
     {
       SqlCommand command = new SqlCommand("store_proc_name", connection);

       command.CommandType = CommandType.StoredProcedure;

       command.Parameters.AddRange(sqlParams.ToArray());

       int results = command.ExecuteNonQuery();

       return (int) paramOutId.Value;
     }
     finally
     {
       CloseConnection(connection);
     }

   }

}

最佳答案

很遗憾,您无法找到一种工具来将您的数据库置于已知状态并让您针对数据库运行 CustomerRepository 以测试 CustomerRepository。但是,答案不是开始使用模拟来模拟所有 ADO 调用。通过这样做,您最终创建了一个单元测试,它并不真正测试任何逻辑:它只是测试代码是否按照您认为应该编写的方式编写。

假设我最终编写了一个 SQL INSERT 作为我在 SQL 数据库中创建客户的命令。现在假设我们正在进行更改,以便客户表具有不同的字段(这会破坏我们的 INSERT 命令)并且现在我们应该使用存储过程来创建客户。带有模拟的测试仍然会通过,即使它正在测试的实现现在被破坏了。此外,如果您修复了使用存储过程的实现,您的单元测试现在将失败。如果单元测试在本应失败时继续通过,但在您修复系统后却失败了,那么单元测试的意义何在?

参见 this question对于一些可能的选择。看起来标记的答案实际上只是最终使用 IKVM 在 C# 中使用 DBUnit。

因此,可能还有其他途径可以继续探索,但模拟 ADO 调用只会导致无法真正测试任何重要内容的脆弱测试。

关于c# - 单元测试数据访问层的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15000908/

相关文章:

c# - 提高 REST 服务的性能

c# - 转义 URL 中的反斜杠

c# - Visual Studio (C#) - 模拟 Win32 按钮按下

java - 让我的 Spring 测试切片扫描单个类而不是整个包

python - 我应该在哪里保存我的测试 Assets ?

c# - 接受任何枚举的方法

c++ - 使用 Visual Studio 2019 和 cmake 进行谷歌测试

c# - 何时使用单元测试与 BDD 测试

unit-testing - 如何对pubsub进行单元测试接收回调

c# - SQLiteConnection 类中的 "SetPassword"或 "ChangePassword"在哪里?