Junit перед классом (не статическим)
Есть ли какие-либо рекомендации по тому, чтобы Junit выполнял функцию один раз в тестовом файле, и он также не должен быть статическим.
как @BeforeClass
для нестатической функции?
Вот уродливое решение:
@Before void init(){
if (init.get() == false){
init.set(true);
// do once block
}
}
Ну, это то, чего я не хочу делать, и я ищу интегрированное решение junit.
Ответы
Ответ 1
Если вы не хотите устанавливать статические инициализаторы для однократной инициализации и не особенно разбираетесь в использовании JUnit, посмотрите TestNG. TestNG поддерживает нестационарную однократную инициализацию с различными параметрами конфигурации, используя аннотации.
В TestNG это будет эквивалентно:
@org.testng.annotations.BeforeClass
public void setUpOnce() {
// One time initialization.
}
Для отрыва,
@org.testng.annotations.AfterClass
public void tearDownOnce() {
// One time tear down.
}
Для эквивалента TestNG для JUnit 4 @Before
и @After
вы можете использовать @BeforeMethod
и @AfterMethod
соответственно.
Ответ 2
Использовать пустой конструктор - самое простое решение. Вы все еще можете переопределить конструктор в расширенном классе.
Но это не оптимально при всем наследовании. Вот почему вместо этого JUnit 4 использует аннотации.
Другой вариант - создать вспомогательный метод в классе factory/util и позволить этому методу выполнить свою работу.
Если вы используете Spring, вам следует рассмотреть возможность использования аннотации @TestExecutionListeners
. Что-то вроде этого теста:
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({CustomTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class})
@ContextConfiguration("test-config.xml")
public class DemoTest {
Spring AbstractTestExecutionListener
содержит, например, этот пустой метод, который вы можете переопределить:
public void beforeTestClass(TestContext testContext) throws Exception {
/* no-op */
}
ПРИМЕЧАНИЕ: НЕ пропускайте и не пропускайте DependencyInjectionTestExecutionListener
при добавлении пользовательских TestExecutionListeners
. Если вы это сделаете, все autowires будут null
.
Ответ 3
Простой оператор if тоже работает очень хорошо:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class myTest {
public static boolean dbInit = false;
@Autowired
DbUtils dbUtils;
@Before
public void setUp(){
if(!dbInit){
dbUtils.dropTables();
dbUtils.createTables();
dbInit = true;
}
}
...
Ответ 4
Легко используйте аннотации @BeforeAllMethods
/@AfterAllMethods
для запуска метода внутри контекста экземпляра (нестатического), где будут доступны все введенные значения.
Для этого есть специальная библиотека тестирования:
https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before-after-spring-test-runner/0.1.0
https://bitbucket.org/radistao/before-after-spring-test-runner/
Единственное ограничение: работает только для весеннего тестирования.
(Я разработчик этой библиотеки тестирования)
Ответ 5
Я никогда не пробовал, но, может быть, вы можете создать конструктор без аргументов и вызвать функцию оттуда?
Ответ 6
ОБНОВЛЕНИЕ: Пожалуйста, посмотрите комментарий Черри, почему предложение ниже является ошибочным. (Я держу ответ здесь, а не удаляю, поскольку комментарий может предоставить полезную информацию другим о том, почему это не работает.)
Другой вариант, который стоит рассмотреть, если использовать внедрение зависимостей (например, Spring), это @PostConstruct
. Это будет гарантировать, что внедрение зависимостей завершено, что не будет иметь место в конструкторе:
@PostConstruct
public void init() {
// One-time initialization...
}
Ответ 7
В статье обсуждаются 2 очень приятных решения этой проблемы:
- "clean" junit с пользовательским Runner (используя интерфейс, но вы можете расширить его с помощью специальной аннотации, например, @BeforeInstance).
- Spring исполнители, упомянутые ранее в Espen.
Ответ 8
Просто используйте @BeforeClass
:
@BeforeClass
public static void init() {
}
Для init
не имеет смысла быть нестатическим, потому что каждый тест запускается в отдельном экземпляре. Экземпляр
что init
выполняется, не будет соответствовать экземпляру любого теста.
Единственная причина, по которой вы хотите, чтобы она была нестатической, - это переопределить ее в подклассах, но вы можете сделать это
со статическими методами тоже. Просто используйте одно и то же имя, и будет вызван только метод подкласса init
.