Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.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
Unit testing 如何有效地对使用ADO.NET和SQL Server与NUnit的DAL进行单元测试?_Unit Testing_C# 4.0_Mocking_Nunit_Data Access Layer - Fatal编程技术网

Unit testing 如何有效地对使用ADO.NET和SQL Server与NUnit的DAL进行单元测试?

Unit testing 如何有效地对使用ADO.NET和SQL Server与NUnit的DAL进行单元测试?,unit-testing,c#-4.0,mocking,nunit,data-access-layer,Unit Testing,C# 4.0,Mocking,Nunit,Data Access Layer,因此,在C#中有一个DAL,它使用存储库模式,并且每个存储库都有一个接口。它由ADO.NET、MS SQL Server和存储过程调用支持 这对于在其他地方进行单元测试时在存储库中使用它是非常好的,我喜欢它 然而,我想为DAL本身添加一些单元测试。最好使用犀牛模型和努尼特。然而,如果有确凿的证据表明它可以做一些Rhino在这个问题上做不到的事情,我愿意改用MoQ 我不希望它在单元测试期间与任何DB对话,以保持它们更“纯净”,同时仍然有效地测试DAL本身。但是,如果您不能在DAL不与DB对话的情况

因此,在C#中有一个DAL,它使用存储库模式,并且每个存储库都有一个接口。它由ADO.NET、MS SQL Server和存储过程调用支持

这对于在其他地方进行单元测试时在存储库中使用它是非常好的,我喜欢它

然而,我想为DAL本身添加一些单元测试。最好使用犀牛模型和努尼特。然而,如果有确凿的证据表明它可以做一些Rhino在这个问题上做不到的事情,我愿意改用MoQ

我不希望它在单元测试期间与任何DB对话,以保持它们更“纯净”,同时仍然有效地测试DAL本身。但是,如果您不能在DAL不与DB对话的情况下真正有效地对其本身进行单元测试,那么有哪些替代方案可以是内存替换或基于可移植文件的替换,这些替代方案与SQL Server的版本以及相同的SqlConnection和SqlCommand调用兼容

如果需要,可以对DAL进行重构,使其更易于注入,只要它不会同时使设计过于复杂。已经在使用MicrosoftUnity,用于具有存储库模式的DI。

这些单元测试到底要测试什么?考虑到典型的DAL代码很少比将实际工作委托给第三方数据访问代码(ADO.NET、EntityFramework、NHibernate)更重要

我很少使用ADO.NET,但我认为这个NHibernate示例已经足够了:

public User GetUser(int id)
{
    using (var session = sessionFactory.OpenSession())
    {
        return session.Get<User>(id);
    }
}
public用户GetUser(int-id)
{
使用(var session=sessionFactory.OpenSession())
{
返回会话.Get(id);
}
}
当然,假设代码编写正确,所有依赖项(
sessionFactory
即)都将通过接口传递,因此易于存根,因此编写单元测试是可能的(您只需模拟大量内容即可)

纯粹主义的方法是编写这样的单元测试,因为它是另一个数据点,证明您的代码确实执行了您的假设(调用
Get
)。但是,请注意,这样的测试成本相当高,因为您基本上必须对提供者进行的整个数据库访问进行存根(mocking
sessionFactory
以返回mocked会话,然后检查是否进行了调用)

这是一个很难做出的决定(在本例中是否遵循纯粹主义的方法),因为您无论如何都必须使用真实的数据库进行编写。这些测试将覆盖与您编写的单元测试完全相同的领域,但工作在真实环境中(而不是存根环境)

根据我的经验,单元测试DAL通常不值得它提供的好处,尤其是与它相当高的成本(为单元测试编写代码以存根数据库环境所花费的时间)和适当的集成测试套件的存在形成对比时

最后,我建议不要在任何类型的测试中使用内存数据库。原因如下:

  • 很慢
  • 它有几个可能难以控制的故障点(ORM配置、内存数据库设置、可能无效的测试数据)
  • 让您错误地感觉到正在进行集成测试(而您并没有这样做;内存中的数据库的行为可能与实际的生产数据库完全不同)

除非您可以将完全相同的数据库加载到内存中,否则请坚持使用适当的集成测试(这将是DAL测试优先级)和独立的单元测试备份(只有在您有能力编写它们的情况下)。

很抱歉,如果我不清楚,这只是ADO.NET、SQL Server和存储过程,根本没有ORM。单元测试将测试您的SQL是否有效,以及您是否正在将SQL的结果转换为存储库接口返回的POCO。您希望确保DAL具有有效的SQL语句并正确传递参数,并且数据类型的转换工作正常。@RodneyFoley:是的,编写此类测试的成本仍然很高(很难截取任何类型的ORM或ADO代码)。您基本上完成了集成测试的工作。请注意,这些测试将是非常脆弱的,因为SQL中最轻微的更改(比如格式化),即使应用程序工作没有任何更改,也会破坏单元测试。我不是说“不要那样做”;我警告说,这些测试将是昂贵的,而且在集成测试中已经有了廉价的替代方案(无论如何,你应该有)。我同意你在回答中的陈述。我想我将要做的是针对正确转换的类型转换编写单元测试,然后将其余部分推到我们的集成测试中,并用它来完成。更糟糕的是,对于快速开发人员健全性检查,我可能会编写一些单元测试,这些单元测试实际上是一个带有ignore标志的集成测试,以便在签入之前更改SQL语句时可以根据需要运行。谢谢吉米!