#java #junit
#java #junit
Вопрос:
Я получил два тестовых класса: A и B. Основная проблема заключается в том, что JUnit вводит @BeforeClass из B перед выполнением @AfterClass из A.
Обычно это не имеет большого значения, но теперь мне приходится работать с общей базой данных, и таким образом она терпит неудачу.
Пример:
public class A {
@AfterClass
public static void clearDb(){
try{
...
EntityManager em = ..
em.getTransaction().begin();
em.createQuery("DELETE FROM ClassName").executeUpdate();
em.getTransaction().commit();
}catch(...){...}
}
@Test
public test(){
...
}
}
public class B {
@BeforeClass
public static void clearDb(){
try{
...
EntityManager em = ..
em.getTransaction().begin();
em.clear();
em.persist(...)
em.getTransaction().commit();
}catch(...){...}
}
@Test
public test(){
...
}
}
Подключение: jdbc: h2: mem:test; DB_CLOSE_DELAY= -1
Мой вопрос: есть ли способ заставить JUnit обрабатывать как единый поток или подождать, пока другой класс действительно очистит свой материал.
Комментарии:
1. Вероятно, одним из способов было бы иметь внешний флаг, который
@AfterClass
метод изменяет после того, как он сделал все необходимое, и@BeforeClass
метод должен ждать, пока этот флаг не будет установлен.2. Распараллеливание основано на том, как вы выполняете свои тесты. Используете ли вы Maven (безошибочно) или что-то еще?
3. Я думаю, что по умолчанию JUnit запускает тесты в одном потоке. Какой бегун вы используете?
4. Я использую простой JUnit в проекте maven. Если я запускаю его с помощью maven test, все в порядке, но средство проверки запускает его как тесты JUnit…
Ответ №1:
Вы изучали использование аннотации правила JUnit?
Вы можете создать абстрактный класс, который обрабатывает состояние базы данных
import org.junit.Rule;
import org.junit.rules.ExternalResource;
public abstract class AbstractTest {
public Object dbConnection;
@Rule
public ExternalResource resource = new ExternalResource() {
@Override
protected void before() {
System.out.println("Setting up resource");
// set up dbConnection
}
@Override
protected void after() {
System.out.println("Cleaning up resource");
// clean db dbConnection
}
};
public Object getDbConnection() {
return dbConnection;
}
}
Тогда ваши тесты расширят ваш абстрактный класс
import org.junit.Assert;
import org.junit.Test;
public class SampleTest extends AbstractTest {
@Test
public void firstTest() {
Object connection = getDbConnection();
// interact with db using the provided connection
System.out.println("do work 1");
}
@Test
public void secondTest() {
Object connection = getDbConnection();
System.out.println("do work 2");
}
}
Комментарии:
1. Я позабочусь об этом решении, но, я думаю, вы неправильно поняли мой вопрос. Проблема в том, что у меня разные классы тестов, а не две разные функции, известные как @ Tests. Как я вижу, вы нашли решение другой проблемы. Основная проблема заключается в том, что многопоточный запуск запускает @ BeforeClass второго теста до того, как @ AfterClass первого мог быть завершен.
Ответ №2:
Старая проблема, но если кому-то это нужно:
Как мне сообщили из многих мест, невозможно гарантировать более позднее.@BeforeClass и ранее.Порядок методов @AfterClass. Окончательное решение заключалось в том, что я использовал разные базы данных H2.