如何使用NUnit测试与数据库相关的代码? [英] How do I test database-related code with NUnit?

查看:188
本文介绍了如何使用NUnit测试与数据库相关的代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用NUnit编写单元测试命中数据库。我想让数据库在每个测试的一致状态。我认为交易将允许我撤销每个测试,所以我搜索,发现几个文章从2004-05的主题:

I want to write unit tests with NUnit that hit the database. I'd like to have the database in a consistent state for each test. I thought transactions would allow me to "undo" each test so I searched around and found several articles from 2004-05 on the topic:

  • http://weblogs.asp.net/rosherove/archive/2004/07/12/180189.aspx
  • http://weblogs.asp.net/rosherove/archive/2004/10/05/238201.aspx
  • http://davidhayden.com/blog/dave/archive/2004/07/12/365.aspx
  • http://haacked.com/archive/2005/12/28/11377.aspx

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

These seem to resolve around implementing a custom attribute for NUnit which builds in the ability to rollback DB operations after each test executes.

这很棒,但是...


  1. 这个功能是否存在于NUnit本身的某处?

  2. 最近4年?

  3. 这是否仍然是测试数据库相关代码的最佳方法?






编辑:这不是我想测试我的DAL明确,它更多是我想测试我的代码与数据库交互。对于这些测试是无触摸和可重复的,如果我可以重置数据库后每一个都会很棒。


it's not that I want to test my DAL specifically, it's more that I want to test pieces of my code that interact with the database. For these tests to be "no-touch" and repeatable, it'd be awesome if I could reset the database after each one.

此外,我想缓解进入现在没有测试地点的现有项目。因此,我几乎不能为每次测试从头开始编写数据库和数据。

Further, I want to ease this into an existing project that has no testing place at the moment. For that reason, I can't practically script up a database and data from scratch for each test.

推荐答案

NUnit现在有一个[回滚]属性,但我更喜欢做一个不同的方式。我使用 TransactionScope 类。有几种方法可以使用它。

NUnit now has a [Rollback] attribute, but I prefer to do it a different way. I use the TransactionScope class. There are a couple of ways to use it.

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

因为你没有告诉TransactionScope提交它,它会自动回滚。

Since you didn't tell the TransactionScope to commit it will rollback automatically. It works even if an assertion fails or some other exception is thrown.

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

The other way is to use the [SetUp] to create the TransactionScope and [TearDown] to call Dispose on it. It cuts out some code duplication, but accomplishes the same thing.

[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被调用。

This is as safe as the using statement in an individual test because NUnit will guarantee that TearDown is called.

我说的所有我认为测试命中数据库不是真正的单元测试。我仍然写他们,但我认为他们作为集成测试。我仍然认为他们提供价值。我经常使用它的一个地方是在测试LINQ to SQL代码。我不使用设计师。我手写DTO的和属性。我已经知道错了。集成测试有助于抓住我的错误。

Having said all that I do think that tests that hit the database are not really unit tests. I still write them, but I think of them as integration tests. I still see them as providing value. One place I use them often is in testing LINQ to SQL code. I don't use the designer. I hand write the DTO's and attributes. I've been known to get it wrong. The integration tests help catch my mistake.

这篇关于如何使用NUnit测试与数据库相关的代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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