JUnit @BeforeClass нестатический работает для Spring загрузочного приложения
JUnit @BeforeClass
аннотация должна быть объявлена статической, если вы хотите, чтобы она запускалась один раз перед всеми методами @Test
. Однако это нельзя использовать с инъекцией зависимостей.
Я хочу очистить базу данных, чтобы я @Autowire
с помощью Spring Boot, один раз, прежде чем запускать тесты JUnit. Я не могу @Autowire
статические поля, поэтому мне нужно подумать о работе. Любые идеи?
Ответы
Ответ 1
Просто используйте @Before
(вместо @BeforeClass
) (или BeforeTransaction
(в зависимости от того, как вы инициализируете базу данных)). Эта аннотация должна быть привязана к нестатическиму общедоступному методу.
Конечно: @Before
запускается до КАЖДОГО метода тестового случая (не как @BeforeClass
, который запускается только один раз.) Но если вы хотите запустить его ровно один раз, используйте поле статического маркера.
private static boolean initialized = false;
...
@Before
public void initializeDB() {
if (!initialized) {
... //your db initialization
initialized = true;
}
}
---
Ответ 2
Посмотрите на библиотеку DBUnit - она предназначена для выполнения действий, которые вы описываете. Он может создавать и срывать экземпляры базы данных и предоставляет вам простые способы сделать это.
Ответ 3
Попробуйте это решение:
fooobar.com/questions/81653/...:
с аннотациями @BeforeAllMethods
/@AfterAllMethods
вы можете выполнить любой метод в классе Test в контексте экземпляра, где доступны все введенные значения.
Ответ 4
Хотя принятый ответ умный, кажется хакерским. Вы пробовали использовать обычный конструктор?
public class MyJUnitTest {
public MyJUnitTest() {
// code for initializeDB
}
// Tests
}
Ответ 5
Есть несколько решений этой проблемы:
1- Как упоминалось @Ralph, вы можете использовать аннотацию Junit @Before или @BeforeEach и использовать логическую переменную в качестве флага. Тем не менее, это решение кажется обходным решением! Потому что вы злоупотребляете им, и в некоторых случаях это может сбить с толку.
2- Вместо этого вы можете использовать TestNG, и вам больше не нужно будет использовать статические методы, поэтому вы можете использовать внедренные объекты Spring. Тем не менее, это решение кажется проблематичным! Потребуется время и работа, чтобы перейти с вашей текущей тестовой среды на TestNG.
3- Третьим решением было бы использование Конструктора. Тем не менее, это решение будет проблематичным для инъекции в наследство.
4- Наконец, я бы предложил использовать @PostConstruct, созданный для таких случаев. Смотрите простой пример кода ниже:
@PostConstruct
public void init(){
initDatabase();
}
Ответ 6
Для JUnit5
: Порядок выполнения теста и @TestInstance(Lifecycle.PER_CLASS)
Пример Kotlin:
@ExtendWith(SpringExtension::class)
@TestInstance(PER_CLASS)
class BeforeInstanceTests {
private var initialized: String = ""
private val callList: MutableList<String> = ArrayList()
@BeforeAll
fun beforeAllNonStatic() {
initialized = "initialized"
assertEquals(0, callList.size)
}
@Test
fun test1() {
assertEquals("initialized", initialized)
callList.add("test1")
}
@Test
fun test2() {
assertEquals("initialized", initialized)
callList.add("test2")
}
@Test
fun test3() {
assertEquals("initialized", initialized)
callList.add("test3")
}
@AfterAll
fun afterAllNonStatic() {
assertEquals("initialized", initialized)
assertEquals(3, callList.size)
assertTrue(callList.contains("test1"))
assertTrue(callList.contains("test2"))
assertTrue(callList.contains("test3"))
callList.clear()
initialized = ""
}
}