Подтвердить что ты не робот

Junit перед классом (не статическим)

Есть ли какие-либо рекомендации по тому, чтобы Junit выполнял функцию один раз в тестовом файле, и он также не должен быть статическим.

как @BeforeClass для нестатической функции?

Вот уродливое решение:

@Before void init(){
    if (init.get() == false){
        init.set(true);
        // do once block
    }
}

Ну, это то, чего я не хочу делать, и я ищу интегрированное решение junit.

4b9b3361

Ответ 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.