如何确保在测试后始终执行数据库清理? [英] How to ensure that database cleanup is always performed after a test?

查看:32
本文介绍了如何确保在测试后始终执行数据库清理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下单元测试示例.评论几乎解释了我的问题.

Consider the following example of a unit test. The comments pretty much explain my problem.

[TestMethod]
public void MyTestMethod()
{

  //generate some objects in the database
  ...

  //make an assert that fails sometimes (for example purposes, this fails always)
  Assert.IsTrue(false);

  //TODO: how do we clean up the data generated in the database now that the test has ended here?

}

推荐答案

有两种方法可以做到这一点.一个正在使用 TestInitialize 和 TestCleanup 属性在测试类中的方法上.它们将始终分别在测试前后运行.

There are two ways to do this. One is using TestInitialize and TestCleanup attributes on methods in the test class. They will always be run before and after the test, respectively.

另一种方法是利用测试失败通过异常传播到测试运行器的事实.这意味着测试中的 try { } finally { } 块可用于在断言失败后清理任何内容.

Another way is to use the fact that test failures are propagated to the test runner via exceptions. This means that a try { } finally { } block in your test can be used clean up anything after an assert fails.

[TestMethod]
public void FooTest()
{
  try
  {
     // setup some database objects
     Foo foo = new Foo();
     Bar bar = new Bar(foo);
     Assert.Fail();
  }
  finally
  {
     // remove database objects.
  }
}

try/finally 清理可能会变得非常混乱,因为有很多对象需要清理.我的团队倾向于使用实现 IDisposable 的辅助类.它跟踪创建了哪些对象并将它们推送到堆栈上.当 Dispose 被调用时,项目从堆栈中弹出并从数据库中删除.

The try/finally cleanup can get really messy is there are a lot of objects to cleanup. What my team has leaned towards is a helper class which implements IDisposable. It tracks what objects have been created and pushes them onto a stack. When Dispose is called the items are popped off the stack and removed from the database.

[TestMethod]
public void FooTest()
{
  using (FooBarDatabaseContext context = new FooBarDatabaseContext())
  {
    // setup some db objects.
    Foo foo = context.NewFoo();
    Bar bar = context.NewBar(foo);
    Assert.Fail();
  } // calls dispose. deletes bar, then foo.
}

这具有将构造函数包装在方法调用中的额外好处.如果构造函数签名发生变化,我们可以轻松修改测试代码.

This has the added benefit of wrapping the constructors in method calls. If constructor signatures change we can easily modify the test code.

这篇关于如何确保在测试后始终执行数据库清理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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