数据访问层单元测试的方式 [英] Ways of unit testing data access layer

查看:69
本文介绍了数据访问层单元测试的方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have be trying to look for an effective way in unit testing my data access layer in C#. I'm primary a Java developer and have only used C# for about 6 months, in the past i've used a library called DBUnit to test against a known state database. I haven't been able to find a similar active library that can be used, closest seems to be nDBUnit but it hasn't been active for awhile now.

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

There seems to be a lot of conflicting methods on how and why in C#. Ideally I want to test the data access layer using mocking without the need to connect to a database and then unit test the store procedure in a separate set of tests.

在我正在使用的系统中,数据访问层是使用ADO.net(不使用实体框架)来调用SQL Server上的存储过程.

In the system I'm working on, the data access layer is to use ADO.net (without the use of the Entity Framework) to call store procedures on a SQL Server.

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

Below is a sample code of what I have to work with; to go down the mocking path, I would have to be able to mock the SqlCommand (using IDbCommand) and/or mock the SqlConnection.

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

So my question is what seems to be the best way (if there is such a thing) to do this? So far the only way would be to make Proxy object that is passed into the constructor so it can return the mocked Sql* objects for testing.

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

I haven't had a chance to look at all the available C# mock libraries available yet.

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调用.这样,您最终创建的单元测试实际上并没有测试任何逻辑:它只是在测试代码是按照您认为应该编写的方式编写的.

It's unfortunate that you can't find a tool that puts your database into a known state and lets you run your CustomerRepository against the database to test the CustomerRepository. However, the answer is not to start using mocks to mock out all of the ADO calls. By doing that, you end up creating a unit test that doesn't really test any logic: it's just testing that the code is written the way you think it should be written.

比方说,我最终以编写SQL INSERT作为命令在SQL数据库中创建客户.现在,我们要进行更改,以便客户表具有不同的字段(这会破坏INSERT命令),现在我们应该使用存储过程来创建客户.即使使用测试的实现现在已被破坏,使用模拟的测试仍将通过.此外,如果您将实现固定为使用存储过程,则单元测试现在将失败.如果单元测试在应该失败的情况下继续通过,但在修复系统后又失败了,那该怎么办呢?

Let's say that I end up writing a SQL INSERT as my command to create the customer in the SQL database. Now let's say that we're making a change so that the customer table has different fields (that breaks our INSERT command) and that now we should be using a stored procedure to create the customer. The test with mocks would still pass, even though the implementation it's testing is now broken. Additionally, if you fixed the implementation to use stored procedures, your unit tests would now fail. What is the point of a unit test if it continues to pass when it should fail but then would fail when you fixed the system?

请参阅此问题,以获取其他可能的选择.看来,已标记的答案实际上是最终使用IKVM在C#中使用DBUnit.

See this question for some possible alternatives. It looks like the marked answer is to actually just end up using DBUnit in C# using IKVM.

因此,可能还有其他途径可以继续探索,但是模拟ADO调用只会导致脆弱的测试,而实际上并没有测试任何重要的东西.

So, there might be alternative avenues to continue to explore, but mocking the ADO calls is just going to lead to brittle tests that don't really test anything important.

这篇关于数据访问层单元测试的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆