在所有@ Before发生之后如何运行?

时间:2012-11-02 13:41:02

标签: junit

我们在层次结构中使用@ Before,以便在测试执行之前将一些测试数据插入到数据库中。我想在@Test开始运行之前将所有数据提交到数据库。

执行此操作的一种方法是将数据提交为此测试类'@Before方法的最后一步。但是我们有数百个这样的类,并且不想进入并修改所有这些类。

我玩过ExternalResource @Rule和TestWatcher @Rule ......但他们没有办法在所有@ Before发生之后挂钩。

我想我需要建立一个自定义的TestRunner才能做到这一点。

这是正确的轨道吗?

2 个答案:

答案 0 :(得分:0)

你在寻找什么,似乎与我不一致。设置一些数据并提交它们是非常接近的操作,不应该属于不同的地方。相反,我宁愿将它们放入一个函数中,并将实际参数设置为要插入的值来调用它。或者使用SQL字符串作为实际参数。并从@Before

调用此结尾

如果你坚持,那就没问题了。为您的Junit类创建后代类:

package ...;
import org.junit.Before;
public class NewAndBetterYourTest1 extends YourTest1 {
    @Override
    @Before
    public void setUp() {
        super.setUp(); // this is where you are setting everything.
        makeCommits();
    }
}

只是不要忘记启动这些新测试

答案 1 :(得分:0)

虽然在没有自定义Runner的情况下无法完成您的要求,但您可以确保@Before方法中创建的所有数据都使用规则提交:

public class LocalDatabase extends ExternalResource {
  private DataSource dataSource;

  @Override
  protected void before() {
    dataSource = createLocalDatabase();
  }

  @Override
  protected void after() {
    try {
      destoyLocalDatabase(dataSource);
    } finally {
      dataSource = null;
    }
  }

  public void run(Callback callback) {
    if (dataSource == null) {
      throw new IllegalStateException("No DataSource");
    }
    Collection con = null;
    try {
      con = ds.getConnection(DB_USERNAME, PASSWORD);
      callback.execute(con);
      con.commit();
    } finally {
      if (con != null) con.close();
    }
  }

您可以在基类中将其作为规则:

public DatabaseTest {
  @Rule
  public LocalDatabase final localDatabase = new LocalDatabase();
}

并且可以在任何子类

中的@Before方法中使用它
public UserDaoTest extends DatabaseTest {

  @Before
  public void populateInitialData() {
    localDatabase.run(new Callback() {
      @Override
      public void execute(Connection con) {
        ...
      }
    });
  }
  ...
}