c# - 如何使用 NUnit 测试与数据库相关的代码?

标签 c# database unit-testing tdd nunit

我想用 NUnit 编写命中数据库的单元测试。我想让数据库在每次测试中都处于一致的状态。我认为事务可以让我“撤消”每个测试,所以我四处搜索并找到了 2004-05 年关于该主题的几篇文章:

这些似乎解决了为 NUnit 实现自定义属性的问题,该属性构建了在每次测试执行后回滚数据库操作的能力。

那很好,但是...

  1. 此功能是否存在于 NUnit 中的某个地方?
  2. 这项技术在过去 4 年中是否有所改进?
  3. 这仍然是测试数据库相关代码的最佳方式吗?

编辑:我并不是想专门测试我的 DAL,而是我想测试与数据库交互的代码片段。为了使这些测试成为“非接触式”且可重复的,如果我可以在每次测试后重置数据库,那就太棒了。

此外,我想将其简化为目前没有测试位置的现有项目。出于这个原因,我实际上无法为每个测试从头开始编写数据库和数据脚本。

最佳答案

NUnit 现在有一个 [Rollback] 属性,但我更喜欢用不同的方式来做。我用 TransactionScope类(class)。有多种使用方法。

[Test]
public void YourTest() 
{
    using (TransactionScope scope = new TransactionScope())
    {
        // your test code here
    }
}

由于您没有告诉 TransactionScope 提交,它将自动回滚。即使断言失败或抛出其他异常,它也能正常工作。

另一种方法是使用 [SetUp] 创建 TransactionScope 并使用 [TearDown] 在其上调用 Dispose。它减少了一些代码重复,但完成了同样的事情。

[TestFixture]
public class YourFixture
{
    private TransactionScope scope;

    [SetUp]
    public void SetUp()
    {
        scope = new TransactionScope();
    }

    [TearDown]
    public void TearDown()
    {
        scope.Dispose();
    }


    [Test]
    public void YourTest() 
    {
        // your test code here
    }
}

这与单独测试中的 using 语句一样安全,因为 NUnit 将保证调用 TearDown。

综上所述,我确实认为命中数据库的测试并不是真正的单元测试。我仍然在写它们,但我认为它们是集成测试。我仍然认为它们提供值(value)。我经常使用它们的一个地方是测试 LINQ to SQL 代码。我不使用设计师。我手写了 DTO 和属性。众所周知,我会弄错。集成测试有助于发现我的错误。

关于c# - 如何使用 NUnit 测试与数据库相关的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/321180/

相关文章:

c# - SSL/TLS - 查找证书时出现问题

python - 在python中完成测试后如何删除测试文件?

c# - 使用 Moq 时在 Dapper 方法上获取 NotSupportedException

c# - 这是检查在 C# 中运行某些代码所花费时间的好方法吗?

c# - 我的基本构造函数如何访问派生实例?

php - codeigniter 保存任何交易

PHP/MySQL - 好友列表 SQL 查询

python - 如何创建具有函数特殊(dunder)属性的 Mock

c# - 无法在 Silverlight DataGrid 列中应用字符串格式

database - 为什么在使用基于法定人数的读写时 Cassandra 不可线性化